66

(用 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
>>> 

为什么对象不允许您向其添加属性?

4

2 回答 2

55

请注意,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__声明采用一系列实例变量,并在每个实例中保留足够的空间来保存每个变量的值。__dict__因为不是为每个实例创建空间,所以节省了空间。

编辑:从评论中回答 ThomasH,OP 的测试类是一个“老式”类。尝试:

>>> 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__定义,但结果是一样的:缺少 a __dict__,这是阻止动态分配属性的原因。我已经重新组织了我的答案以使这一点更清楚(将第二段移到顶部)。

于 2009-08-16T20:34:10.103 回答
4

好问题,我的猜测是它与内置/扩展类型的object事实有关

>>> 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__属性的存在有关,或者更准确地说,setattr()当对象没有__dict__属性时会爆炸。

于 2009-08-16T20:39:41.027 回答