subclases - ¿Por qué no puedes agregar atributos al objeto en Python?
subclases python (2)
Buena pregunta, mi suposición es que tiene que ver con el hecho de que el object
es un tipo incorporado / de extensión .
>>> class test(object):
... pass
...
>>> test.test = 1
>>> object.test = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can''t set attributes of built-in/extension type ''object''
IIRC, esto tiene que ver con la presencia de un atributo __dict__
o, más correctamente, setattr()
explotando cuando el objeto no tiene un atributo __dict__
.
Esta pregunta ya tiene una respuesta aquí:
- No se pueden establecer los atributos de las respuestas de la clase de objeto 6
(Escrito en el shell de Python)
>>> o = object()
>>> o.test = 1
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
o.test = 1
AttributeError: ''object'' object has no attribute ''test''
>>> class test1:
pass
>>> t = test1()
>>> t.test
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
t.test
AttributeError: test1 instance has no attribute ''test''
>>> t.test = 1
>>> t.test
1
>>> class test2(object):
pass
>>> t = test2()
>>> t.test = 1
>>> t.test
1
>>>
¿Por qué el objeto no le permite agregarle atributos?
Tenga en cuenta que una instancia de object
no __dict__
atributo __dict__
:
>>> dir(object())
[''__class__'', ''__delattr__'', ''__doc__'', ''__getattribute__'', ''__hash__'', ''__init__'', ''__new__'', ''__reduce__'', ''__reduce_ex__'', ''__repr__'', ''__setattr__'', ''__str__'']
Un ejemplo para ilustrar este comportamiento en una clase derivada:
>>> class Foo(object):
... __slots__ = {}
...
>>> f = Foo()
>>> f.bar = 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: ''Foo'' object has no attribute ''bar''
Citando de los documentos en las slots
:
[...] La declaración
__slots__
toma una secuencia de variables de instancia y reserva suficiente espacio en cada instancia para mantener un valor para cada variable. El espacio se guarda porque__dict__
no se crea para cada instancia.
EDITAR: para responder a ThomasH a partir de los comentarios, la clase de prueba de OP es una clase "antigua". Tratar:
>>> class test: pass
...
>>> getattr(test(), ''__dict__'')
{}
>>> getattr(object(), ''__dict__'')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: ''object'' object has no attribute ''__dict__''
y notará que hay una instancia de __dict__
. La clase de objeto puede no tener un __slots__
definido, pero el resultado es el mismo: falta de un __dict__
, que es lo que impide la asignación dinámica de un atributo. He reorganizado mi respuesta para aclarar esto (mueva el segundo párrafo a la parte superior).