Python中的结构体对象

19 投票
9 回答
35560 浏览
提问于 2025-04-15 16:51

我想创建一个临时的“结构体”对象,用来保存各种状态标志。我的第一种方法是这样的(像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 个回答

10

我以前也有过同样的问题。我在一个邮件列表里问过,Alex Martelli 指出,object 是 Python 中所有继承的基础。如果 object() 创建了一个有自己字典的类实例,那么 Python 中的每个对象都得有自己的字典,这样会浪费内存。举个例子,TrueFalse 都是对象;显然它们并不需要自己的字典!

我会很高兴如果 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 模块中加入一个标准功能之类的。

20

来自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本来就应该是可读、易维护和易于理解的。

32

创建一个“可以给它添加或获取属性的通用对象”的最简洁方法可能就是:

b = lambda:0

正如其他大多数回答所提到的,还有很多其他方法,但在简洁性上,这个方法几乎没有对手(lambda:0object() 的字符数是一样的...;-)。

撰写回答