2011-04-21 20 views
9

Esto funciona:atributo asignación al objeto incorporado

class MyClass(object): 
    pass 

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

Pero esto no es así:

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

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

Respuesta

7

Python almacena atributos en un dict. Puede agregar atributos a MyClass, vemos 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 no tiene object__dict__ atributo.

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

explicaciones más detalladas:

+1

Gracias! Extraño No encontré estas dos preguntas con las que publicó los enlaces. – Turion

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

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

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

Cuando hereda del objeto que es su clase base así como __builtin__, puede modificar solo su nuevo MyClass que haya definido.

0

Para las clases definidas por el usuario, configuración de un atributo de un objeto es en realidad la modificación de un diccionario de atributos, por lo que puede agregar una nueva entrada en cualquier momento. (Objeto __dict__)

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

Por favor, vea:

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

4

En cuanto a la razón de esto, las palabras de the BDFL himself:

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

Cuestiones relacionadas