(Écrit en Python Shell)
>>> 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
>>>
Pourquoi l'objet ne vous permet-il pas d'y ajouter des attributs?
Notez qu'une instance object
n'a pas __dict__
attribut:
>>> dir(object())
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__']
Un exemple pour illustrer ce comportement dans une classe dérivée:
>>> 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'
Citant la documentation sur slots
:
[...] Le
__slots__
la déclaration prend une séquence de variables d'instance et réserve juste assez d'espace dans chaque instance pour contenir une valeur pour chaque variable. L'espace est économisé car__dict__
n'est pas créé pour chaque instance.
EDIT: Pour répondre à ThomasH à partir des commentaires, la classe de test OP est une classe "à l'ancienne". Essayer:
>>> 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__'
et vous remarquerez qu'il y a un __dict__
exemple. La classe d'objets peut ne pas avoir de __slots__
défini, mais le résultat est le même: absence de __dict__
, ce qui empêche l'affectation dynamique d'un attribut. J'ai réorganisé ma réponse pour rendre cela plus clair (déplacer le deuxième paragraphe vers le haut).
Bonne question, je suppose que cela a à voir avec le fait que object
est un type intégré/extension.
>>> 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, cela a à voir avec la présence d'un attribut __dict__
Ou, plus correctement, setattr()
explosant lorsque l'objet n'a pas d'attribut __dict__
.