Почему вы не можете добавить атрибуты к объекту в 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 56

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() взрывается, когда объект не имеет .