Asignación de atributo a objeto incorporado

Esto funciona:

class MyClass(object): pass someinstance = MyClass() someinstance.myattribute = 42 print someinstance.myattribute >>> 42 

Pero esto no lo hace:

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

¿Por qué? Tengo la sensación de que esto está relacionado con el hecho de que el objeto sea una clase incorporada, pero no me parece satisfactorio, ya que no cambié nada en la statement de MyClass.

Python almacena atributos en un dict. Puedes agregar atributos a MyClass , ver que tiene un __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__'] 

La diferencia importante es que el object no __dict__ atributo __dict__ .

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

Explicaciones más detalladas:

  • No se pueden establecer atributos de clase de objeto
  • ¿Por qué no puedes agregar atributos al objeto en Python?

En cuanto a la razón detrás de esto, las palabras del propio BDFL :

Esto está prohibido intencionalmente para evitar cambios fatales accidentales en los tipos incorporados (fatal para partes del código que nunca pensó). Además, se hace para evitar que los cambios afecten a los diferentes intérpretes que residen en el espacio de direcciones, ya que todos los intérpretes comparten los tipos incorporados (a diferencia de las clases definidas por el usuario).

 >>> type(object) type 'type' >>> type(MyClass) type 'classobj' 

Aquí la diferencia importante es que MyClass es un objeto de clase definido por el usuario. Donde puedes modificar tu clase.

object() sin embargo es un objeto de clase __builtin__ .

Cuando hereda de un objeto que es su clase base y también __builtin__ , solo puede modificar su nueva MyClass que haya definido.

Para las clases definidas por el usuario, establecer un atributo en un objeto en realidad está modificando un diccionario de atributos, por lo que puede agregar una nueva entrada en cualquier momento. (Objeto __dict__ )

Los atributos en los tipos incorporados se implementan de manera diferente, no como un diccionario genérico sino directamente como el diseño de memoria de la implementación subyacente. Debido a que el diccionario no existe y la clase no se puede cambiar en tiempo de ejecución, no puede agregar nuevos valores de atributo a los objetos incorporados.

Por favor mira:

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 = es & ct = clnk & gl = us & client = firefox-a & source = http://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