关于python:内置对象的属性赋值

Attribute assignment to built-in object

本问题已经有最佳答案,请猛点这里访问。

这项工作:

1
2
3
4
5
6
7
class MyClass(object):
    pass

someinstance = MyClass()
someinstance.myattribute = 42
print someinstance.myattribute
>>> 42

但这并不是:

1
2
3
someinstance = object()
someinstance.myattribute = 42
>>> AttributeError: 'object' object has no attribute 'myattribute'

为什么?我有一种感觉,这和作为一个内建类的对象有关,但是我发现这不令人满意,因为我在MyClass的声明中没有更改任何内容。


python将属性存储在dict中。您可以将属性添加到MyClass,请参见它有一个__dict__

1
2
3
4
>>> 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__属性。

1
2
>>> dir(object)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

更详细的解释:

  • 无法设置对象类的属性
  • 为什么不能在python中向对象添加属性?


至于这背后的理由,BDFL本人的话是:

This is prohibited intentionally to prevent accidental fatal changes
to built-in types (fatal to parts of the code that you never though
of). Also, it is done to prevent the changes to affect different
interpreters residing in the address space, since built-in types
(unlike user-defined classes) are shared between all such
interpreters.


1
2
3
4
>>> type(object)
type 'type'
>>> type(MyClass)
type 'classobj'

这里的重要区别是MyClass是一个用户定义的类对象。在那里你可以修改你的类。

但是,object()__builtin__类对象。

当您从属于您的基类和__builtin__的对象继承时,您只能修改您定义的新MyClass


对于用户定义的类,在对象上设置属性实际上是修改属性字典,因此您可以随时添加新条目。(对象的__dict__)

内置类型上的属性以不同的方式实现,不是作为通用字典,而是直接作为底层实现的内存布局。因为字典不存在,并且类不能在运行时更改,所以不能向内置对象添加新的属性值。

请参见:

http://webcache.googleusercontent.com/search?Q=cache:z4to2igbkduj:www.velocityreviews.com/forums/t593269无法设置内置扩展类型的属性。html+setattr+built+in+class&cd=3&hl=en&ct=clnk&gl=us&client=firefox-a&source=www.google.com

http://mail.python.org/pipermail/python-dev/2008-february/077180.html

http://mail.python.org/pipermail/python-list/2010-april/1240731.html