Python中类似C的结构

时间:2020-03-05 18:45:26  来源:igfitidea点击:

有没有一种方法可以在Python中方便地定义类似C的结构?我讨厌写这样的东西:

class MyStruct():
    def __init__(self, field1, field2, field3):
        self.field1 = field1
        self.field2 = field2
        self.field3 = field3

解决方案

回答

字典怎么样?

像这样的东西:

myStruct = {'field1': 'some val', 'field2': 'some val'}

然后,我们可以使用它来操纵值:

print myStruct['field1']
myStruct['field2'] = 'some other values'

值不必是字符串。它们几乎可以是任何其他对象。

回答

我们可以在很多情况下使用元组,而在C中使用结构(例如x,y坐标或者RGB颜色)。

对于其他所有内容,我们都可以使用字典或者类似这样的实用程序类:

>>> class Bunch:
...     def __init__(self, **kwds):
...         self.__dict__.update(kwds)
...
>>> mystruct = Bunch(field1=value1, field2=value2)

我认为"确定性"讨论在此处,已发布的Python Cookbook版本中。

回答

使用命名元组,该元组已添加到Python 2.6的标准库中的collections模块中。如果需要支持Python 2.4,也可以使用Raymond Hettinger的命名元组配方。

这对于基本示例很好,但也涵盖了以后可能会遇到的许多极端情况。我们上面的片段将写为:

from collections import namedtuple
MyStruct = namedtuple("MyStruct", "field1 field2 field3")

可以像下面这样使用新创建的类型:

m = MyStruct("foo", "bar", "baz")

我们还可以使用命名参数:

m = MyStruct(field1="foo", field2="bar", field3="baz")

回答

dF: that's pretty cool... I didn't
  know that I could access the fields in
  a class using dict.
  
  Mark: the situations that I wish I had
  this are precisely when I want a tuple
  but nothing as "heavy" as a
  dictionary.

我们可以使用字典访问类的字段,因为类的字段,其方法及其所有属性都使用dict在内部存储(至少在CPython中)。

...这将引导我们提出第二条评论。相信Python字典是"繁重的"是一个极端的非Python的概念。阅读此类评论会杀死我的Python Zen。这不好。

我们会看到,在声明一个类时,实际上是在围绕字典创建一个非常复杂的包装器,因此,如果有的话,与使用简单的字典相比,我们将增加更多的开销。顺便说一句,开销在任何情况下都是没有意义的。如果我们正在处理对性能有严格要求的应用程序,请使用C或者其他语言。

回答

我们还可以按位置将init参数传递给实例变量

# Abstract struct class       
class Struct:
    def __init__ (self, *argv, **argd):
        if len(argd):
            # Update by dictionary
            self.__dict__.update (argd)
        else:
            # Update by position
            attrs = filter (lambda x: x[0:2] != "__", dir(self))
            for n in range(len(argv)):
                setattr(self, attrs[n], argv[n])

# Specific class
class Point3dStruct (Struct):
    x = 0
    y = 0
    z = 0

pt1 = Point3dStruct()
pt1.x = 10

print pt1.x
print "-"*10

pt2 = Point3dStruct(5, 6)

print pt2.x, pt2.y
print "-"*10

pt3 = Point3dStruct (x=1, y=2, z=3)
print pt3.x, pt3.y, pt3.z
print "-"*10

回答

也许我们正在寻找没有构造函数的Structs:

class Sample:
  name = ''
  average = 0.0
  values = None # list cannot be initialized here!

s1 = Sample()
s1.name = "sample 1"
s1.values = []
s1.values.append(1)
s1.values.append(2)
s1.values.append(3)

s2 = Sample()
s2.name = "sample 2"
s2.values = []
s2.values.append(4)

for v in s1.values:   # prints 1,2,3 --> OK.
  print v
print "***"
for v in s2.values:   # prints 4 --> OK.
  print v