为什么不能在python中添加属性到对象?
(用Python shell编写)
>>> o = object() >>> o.test = 1 Traceback (most recent call last): File "<pyshell#45>", line 1, in <module> o.test = 1 AttributeError: 'object' object has no attribute 'test' >>> class test1: pass >>> t = test1() >>> t.test Traceback (most recent call last): File "<pyshell#50>", line 1, in <module> t.test AttributeError: test1 instance has no attribute 'test' >>> t.test = 1 >>> t.test 1 >>> class test2(object): pass >>> t = test2() >>> t.test = 1 >>> t.test 1 >>>
为什么没有对象允许你添加属性?
注意object
实例没有__dict__
属性:
>>> dir(object()) ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__']
一个例子来说明派生类中的这种行为:
>>> class Foo(object): ... __slots__ = {} ... >>> f = Foo() >>> f.bar = 42 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute 'bar'
从slots
上的文档引用:
[…]
__slots__
声明采用一系列实例variables,并在每个实例中保留足够的空间来为每个variables保存一个值。 保存空间是因为__dict__
不是为每个实例创build的。
编辑:从评论中回答ThomasH,OP的testingclass是一个“旧式”class。 尝试:
>>> class test: pass ... >>> getattr(test(), '__dict__') {} >>> getattr(object(), '__dict__') Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute '__dict__'
你会注意到有一个__dict__
实例。 对象类可能没有定义__slots__
,但结果是相同的:缺less__dict__
,这是防止dynamic分配属性的原因。 我已经整理了我的答案,使其更清晰(将第二段移到顶部)。
好问题,我的猜测是,这是与object
是内置/扩展types的事实有关。
>>> class test(object): ... pass ... >>> test.test = 1 >>> object.test = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't set attributes of built-in/extension type 'object'
IIRC,这与一个__dict__
属性的存在有关,或者更准确地说,当对象没有__dict__
属性时, setattr()
会__dict__
。