Attribute assignment to built-in object [duplicate]
This works:
class MyClass(object):
pass
someinstance = MyClass()
someinstance.myattribute = 42
print someinstance.myattribute
>>> 42
But this doesn't:
someinstance = object()
someinstance.myattribute = 42
>>> AttributeError: 'object' object has no attribute 'myattribute'
Why? I've got a feeling, that this is related to object being a built-in class, but I find this unsatisfactory, since I changed nothing in the declaration of MyClass.
As for the rationale behind this, the words of the BDFL himself:
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.
Python stores attributes in a dict. You can add attributes to MyClass
, see it has a __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__']
The important difference is that object
has no __dict__
attribute.
>>> dir(object)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
More detailed explanations:
- Can't set attributes of object class
- Why can't you add attributes to object in python?
For user-defined classes, setting an attribute on an object is actually modifying an dictionary of attributes, so you can add a new entry at any time. (Object's __dict__
)
Attributes on built-in types are implemented differently, not as generic dictionary but directly as the memory layout of the underlying implementation. Because the dictionary does not exist, and the class cannot be changed at runtime, you cannot add new attribute values to built-in objects.
Please see:
http://webcache.googleusercontent.com/search?q=cache:z4to2IGbKDUJ:www.velocityreviews.com/forums/t593269-cant-set-attributes-of-built-in-extension-type.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
>>> type(object)
type 'type'
>>> type(MyClass)
type 'classobj'
Here the important difference is MyClass
is a user defined class object. Where you can modify your class.
object()
however is a __builtin__
class object.
When you inherit from object which is your base class as well as __builtin__
, you can modify only your new MyClass
that you defined.
精彩评论