Почему вы не можете добавить атрибуты к объекту в python? [дубликат]
этот вопрос уже есть ответ здесь:
(написано в оболочке 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
>>>
почему объект не позволяет добавлять к нему атрибуты?
2 ответа:
заметил, что
object
экземпляр не имеет :>>> dir(object()) ['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__']
пример, иллюстрирующий это поведение в производном классе:
>>> 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'
цитирование из документов на
slots
:[...] The
__slots__
объявление принимает последовательность переменных экземпляра и резервирует достаточно места в каждом экземпляре для хранения значения для каждой переменной. Пространство сохраняется, потому что__dict__
не создается для каждого пример.EDIT: чтобы ответить Томашу из комментариев, тестовый класс OP является классом "старого стиля". Попробуйте:
>>> 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__'
и вы заметите, что есть
__dict__
экземпляра. Класс объекта может не иметь__slots__
определился, но результат тот же: отсутствие__dict__
, что предотвращает динамическое присвоение атрибута. Я реорганизовал свой ответ, чтобы сделать это более ясным (переместите второй абзац наверх).
хороший вопрос, я думаю, что это связано с тем, что
object
это тип разъема / расширения.>>> 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, это связано с наличием или
setattr()
взрывается, когда объект не имеет .