2016-04-24 11 views
2

__weakref__ bezieht sich auf schwache Referenzen. Ich bekomme die ganze Idee hinter schwachen Referenzen und wo ich sie verwenden könnte. Das einzige, was ich nicht in dem folgenden beschrieben erhalten:Warum ist die Klasse .__ weakref__ nicht None, während die Instanz .__ weakref__ keine ist?

hat eine Instanz nicht das Attribut __weakref__ selbst, die sie von der Klasse, also die Instanz erbt__weakref__ aus der Klasse, bedeutet dies, dass A.__weakref__ sollte die gleiche sein wie A().__weakref__:

>>> class A: pass 
... 
>>> A().__dict__   # Each instance starts out as an empty namespace 
{} 
>>> A.__weakref__ is None; 
False 
>>> A().__weakref__ is None #But this is True! 
True 

Warum A.__weakref__ nicht None während instance.__weakref__ ist None ist, obwohl Instanzen __weakref__ aus der Klasse erben?

+0

* "Dies bedeutet, dass' A .__ weakref__ 'ist das gleiche wie' A() .__ weakref__' "* - eindeutig nicht, also ist Ihre Annahme, dass *" Instanzen "__weakref__" von der Klasse "* erben, falsch. 'A .__ weakref__ ist A() .__ weakref__' ergibt" False ". – jonrsharpe

Antwort

3

A-Klasse hat eine __weakref__descriptor object; dies verhält sich genau wie ein property oder ein Verfahren; Nur wenn Sie auf das Attribut eines Objekts zugreifen, wird es automatisch gebunden. Die tatsächlichen Daten für eine schwache Referenz werden in einer C-Struktur gespeichert, einem Teil der Datenstruktur, die Python zur Darstellung von Klassen und Instanzen im Speicher verwendet.

Als solche Fälle brauchen nicht ihr eigenes __weakref__ Attribut. Der Klassendeskriptor ist an die Instanzdatenstruktur gebunden, und der C-Code sucht dann einfach in der rechten C-Struktur nach den benötigten Informationen.

Durch Zugriff auf das Attribut für die Klasse wird das Deskriptorobjekt selbst erstellt. Dies ist nicht None; es ist das Deskriptorobjekt. Bei einem Attribut erzeugt das gebundene Attribut die schwachen Referenzen. Keine schwachen Referenzen, bedeutet None wird zurückgegeben.

Sie können die Beschreiber Verhalten durch den Zugriff auf das Objekt über A.__dict__['__weakref__'] (umgehen den normalen type.__getattribute__() Bindungsverhalten), dann ruft direkt __get__ auf das neu erstellen:

>>> import weakref 
>>> class A(object): pass 
... 
>>> a = A() 
>>> A.__weakref__ 
<attribute '__weakref__' of 'A' objects> 
>>> descriptor = A.__dict__['__weakref__'] 
>>> descriptor.__get__(None, A) 
<attribute '__weakref__' of 'A' objects> 
>>> a = A() 
>>> a.__weakref__ is None 
True 
>>> descriptor.__get__(a) is None 
True 
>>> wr = weakref.ref(a) # add a weak reference 
>>> wr 
<weakref at 0x10bd86d68; to 'A' at 0x10bad3588> 
>>> a.__weakref__ 
<weakref at 0x10bd86d68; to 'A' at 0x10bad3588> 
>>> descriptor.__get__(a) 
<weakref at 0x10bd86d68; to 'A' at 0x10bad3588> 
Verwandte Themen