2009-08-16 14 views
53

(napisany w Pythonie shell)Dlaczego nie możesz dodać atrybutów do obiektu w pythonie?

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

Dlaczego nie sprzeciwia pozwalają na dodawanie atrybutów do niego?

Odpowiedz

38

Należy zauważyć, że instancja object ma __dict__ atrybutów:

>>> dir(object()) 
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__'] 

przykład ilustrujący ten problem w klasie pochodnych:

>>> 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' 

cytować Dokumenty na slots:

[...] Deklaracja __slots__ s sekwencję zmiennych instancji i rezerwuje tylko tyle miejsca w każdym przypadku, aby pomieścić wartość dla każdej zmiennej. Miejsce jest zapisane, ponieważ __dict__ nie jest tworzone dla każdej instancji.

EDYCJA: Aby odpowiedzieć ThomasH z komentarzy, klasa testowa OP jest klasą "starego stylu". Wypróbuj:

, a zauważysz, że istnieje instancja __dict__. Klasa obiektu może nie mieć zdefiniowanej wartości __slots__, ale wynik jest taki sam: brak wartości __dict__, co zapobiega dynamicznemu przypisywaniu atrybutu. Przeorganizowałem swoją odpowiedź, aby to wyjaśnić (przenieś akapit drugi na górę).

+2

Tak więc mówisz, że klasa * object * używa \ _ \ _ slotów \ _ \ _ w taki czy inny sposób, aby zapobiec przypisaniu członków instancji. Czy jest to założenie, czy fakt (tzn. Czy jest to implementacja * obiektu *)? Ponieważ sam brak \ _ \ dict \ _ \ _ z instancji * object * nie jest orientacyjny. Instancje klasy OP * test1 * pokazują ten sam brakujący \ _ \ _ dict \ _ \ _ po wywołaniu z dir(), ale mimo to zezwól na przydział członków instancji. – ThomasH

+1

@ThomasH, zobacz notatkę dodaną do odpowiedzi. – ars

3

Dobre pytanie, przypuszczam, że ma to związek z tym, że object to typu wbudowanego/rozszerzenia.

>>> 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, ma to związek z obecnością atrybutem __dict__ lub, bardziej poprawnie, setattr() wysadzenie gdy obiekt nie posiada atrybut __dict__.

Powiązane problemy