为什么可以';在python中,您不能向对象添加属性吗?

为什么可以';在python中,您不能向对象添加属性吗?,python,attributes,instances,Python,Attributes,Instances,(用pythonshell编写) >o=object() >>>o.test=1 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 o、 测试=1 AttributeError:“对象”对象没有属性“测试” >>>类test1: 通过 >>>t=test1() >>>t检验 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 t、 试验 AttributeError:test1实例没有属性“test” >>>t.test=1 >>>t检验 1. >>>类test2(对象): 通过 >>>t

(用pythonshell编写)

>o=object()
>>>o.test=1
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
o、 测试=1
AttributeError:“对象”对象没有属性“测试”
>>>类test1:
通过
>>>t=test1()
>>>t检验
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
t、 试验
AttributeError:test1实例没有属性“test”
>>>t.test=1
>>>t检验
1.
>>>类test2(对象):
通过
>>>t=test2()
>>>t.test=1
>>>t检验
1.
>>> 

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

请注意,
对象
实例没有
\uuuu dict\uuuu
属性:

>>> 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'

您会注意到有一个
\uuuu dict\uuu
实例。对象类可能没有定义
\uuuuuu slots\uuuu
,但结果是相同的:缺少
\uuuuuuu dict\uuuu
,这是阻止动态分配属性的原因。我重新组织了我的答案,使之更清晰(将第二段移到顶部)。

好问题,我猜这与
对象是内置/扩展类型这一事实有关

>类测试(对象):
...  通过
...
>>>test.test=1
>>>object.test=1
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:无法设置内置/扩展类型“object”的属性

IIRC,这与存在
\uuu dict\uuuu
属性有关,或者更准确地说,当对象没有
\uuu dict\uuuu
属性时,
setattr()
会爆炸。因此,您是说对象类以某种方式使用了uu slots\uu,以防止实例成员的分配。这是一个假设还是一个事实(即,它是在对象的实现中)?因为仅仅从对象实例中不存在u\dict_u_u并不表示。OP的test1类的实例在使用dir()调用时显示相同的缺失_dict__u;,但允许分配实例成员。@ThomasH,请参阅我添加到答案中的注释。
>>> 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'
>>> 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__'
>>> 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'