Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 290
Turion Avatar asked Apr 21 '11 08:04

Turion


3 Answers

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.

like image 84
Claudiu Avatar answered Nov 10 '22 15:11

Claudiu


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

like image 37
elliot42 Avatar answered Nov 10 '22 15:11

elliot42


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?
like image 8
lecodesportif Avatar answered Nov 10 '22 15:11

lecodesportif