这有效:
class MyClass(object):
pass
someinstance = MyClass()
someinstance.myattribute = 42
print someinstance.myattribute
>>> 42
但这不是:
someinstance = object()
someinstance.myattribute = 42
>>> AttributeError: 'object' object has no attribute 'myattribute'
为什么呢?我有一种感觉,这与对象是一个内置类有关,但我发现这不令人满意,因为我在MyClass的声明中没有改变任何内容。
答案 0 :(得分:8)
Python在dict中存储属性。您可以向MyClass
添加属性,看它有__dict__
:
>>> class MyClass(object):
>>> pass
>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
重要的区别是object
没有__dict__
属性。
>>> dir(object)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
更详细的解释:
答案 1 :(得分:6)
关于这背后的理由,the BDFL himself:
的话这是故意禁止意外致命的变化 内置类型(致命的部分代码,你从来没有 的)。此外,它是为了防止更改影响不同 自内置类型以来驻留在地址空间中的解释器 (与用户定义的类不同)在所有这些之间共享 解释器。
答案 2 :(得分:1)
>>> type(object)
type 'type'
>>> type(MyClass)
type 'classobj'
这里的重要区别是MyClass
是用户定义的类对象。你可以在哪里修改你的课程。
object()
但是__builtin__
类对象。
当您继承自作为基类的对象以及__builtin__
时,您只能修改您定义的新MyClass
。
答案 3 :(得分:0)
对于用户定义的类,在对象上设置属性实际上是修改属性字典,因此您可以随时添加新条目。 (对象的__dict__
)
内置类型的属性以不同的方式实现,而不是作为通用字典,而是直接作为底层实现的内存布局。由于字典不存在,并且在运行时无法更改类,因此无法向内置对象添加新属性值。
请参阅:
http://mail.python.org/pipermail/python-dev/2008-February/077180.html
http://mail.python.org/pipermail/python-list/2010-April/1240731.html