tipos subclases privados poo objeto funciones ejemplos definir como clases clase atributos python attributes instances

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í:

(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).