Python中的结构体对象
我想创建一个临时的“结构体”对象,用来保存各种状态标志。我的第一种方法是这样的(像JavaScript那样)
>>> status = object()
>>> status.foo = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
结果完全不是我预期的,因为这个是可以工作的:
>>> class Anon: pass
...
>>> b=Anon()
>>> b.foo = 4
我想这可能是因为 object() 没有 __dict__
这个属性。我不想使用字典,而且假设我不想创建 Anon 对象,还有其他解决办法吗?
9 个回答
我以前也有过同样的问题。我在一个邮件列表里问过,Alex Martelli 指出,object
是 Python 中所有继承的基础。如果 object()
创建了一个有自己字典的类实例,那么 Python 中的每个对象都得有自己的字典,这样会浪费内存。举个例子,True
和 False
都是对象;显然它们并不需要自己的字典!
我会很高兴如果 Python 有某种内置功能,让我可以直接这样写:
x = struct()
x.foo = 1
x.bar = 2
不过,写一个 struct()
是非常简单的:
class struct(object):
pass
或者你可以写一个稍微复杂一点的:
class struct(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
这个更复杂的版本让你可以这样做:
x = struct(foo=1, bar=2)
print(x.foo) # prints 1
print(x.bar) # prints 2
x.baz = 3
print(x.baz) # prints 3
但是写 struct()
实在是太简单了,所以我想它没有被认为值得加入到语言里。也许我们应该推动在 collections
模块中加入一个标准功能之类的。
来自Python官方文档:
9.7. 一些杂项
有时候,我们需要一种数据类型,类似于Pascal的“记录”或C语言的“结构体”,可以把几个命名的数据项放在一起。定义一个空的类就可以很好地实现这个功能:
class Employee:
pass
john = Employee() # Create an empty employee record
# Fill the fields of the record
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000
这看起来很自然,也很简单:符合Python的风格。记住Python的哲学! “简单比复杂好”(第3条)和“如果实现容易解释,那可能是个好主意”(第11条)
此外,struct
其实就是一个带有公共成员的class
(也就是说,struct{};
和class{public:};
在C++中是完全一样的)。你不应该考虑这一点,避免在你的Python程序中使用不必要的结构吗?Python本来就应该是可读、易维护和易于理解的。
创建一个“可以给它添加或获取属性的通用对象”的最简洁方法可能就是:
b = lambda:0
正如其他大多数回答所提到的,还有很多其他方法,但在简洁性上,这个方法几乎没有对手(lambda:0
和 object()
的字符数是一样的...;-)。