Secondo la documentazione del modulo weakref:
Nel seguito, il termine referente significa che l'oggetto che viene indicato da un riferimento debole.
Un riferimento debole per un oggetto non è sufficiente per tenere in vita l'oggetto: quando gli unici rimasti riferimenti a un referente sono riferimenti deboli, spazzatura raccolta è libera di distruggere il referente e riutilizzare la sua memoria per qualcos'altro.
Che cosa sta accadendo con MyCallbackA è che si sta tenendo un riferimento ad essa nei casi di A, grazie al -
self.MyCallbackA = MyCallbackA
Ora, non v'è alcun riferimento al metodo MyCallbackB vincolato nel codice. È tenuto solo in una classe .__ __.__ dict__ come metodo non associato. Fondamentalmente, un metodo associato viene creato (e restituito a te) quando fai self.methodName. (AFAIK, un metodo associato funziona come una proprietà -utilizzando un descrittore (di sola lettura): almeno per le nuove classi di stile.Sono sicuro, qualcosa di simile vale a dire senza descrittori che si verificano per classi di vecchio stile. qualcuno più esperto per verificare l'affermazione relativa alle vecchie classi di stile.) Quindi, self.MyCallbackB muore non appena viene creato il weakref, perché non vi è alcun riferimento forte ad esso!
Le mie conclusioni si basano su: -
import weakref
#Trace is called when the object is deleted! - see weakref docs.
def trace(x):
print "Del MycallbackB"
class A(object):
def __init__(self):
def MyCallbackA():
print 'MyCallbackA'
self.MyCallbackA = MyCallbackA
self._testA = weakref.proxy(self.MyCallbackA)
print "Create MyCallbackB"
# To fix it, do -
# self.MyCallbackB = self.MyCallBackB
# The name on the LHS could be anything, even foo!
self._testB = weakref.proxy(self.MyCallbackB, trace)
print "Done playing with MyCallbackB"
def MyCallbackB(self):
print 'MyCallbackB'
def test_a(self):
self._testA()
def test_b(self):
self._testB()
if __name__ == '__main__':
a = A()
#print a.__class__.__dict__["MyCallbackB"]
a.test_a()
uscita
Crea MyCallbackB
Del MycallbackB
Fatto a giocare con MyCallbackB
MyCallbackA
Nota:
Ho provato a verificare questo per le classi di vecchio stile. Si è scoperto che "la stampa a.test_a .__ get__" uscite -
<method-wrapper '__get__' of instancemethod object at 0xb7d7ffcc>
sia per i vecchi e nuovi stili di classi. Quindi potrebbe non essere realmente un descrittore, solo qualcosa di descrittore. In ogni caso, il punto è che un oggetto metodo vincolato viene creato quando si accede ad un metodo di istanza tramite sé, e se non si mantiene un forte riferimento ad esso, esso verrà eliminato.
per Python 3 sostituire '' item.im_func' con voce .__ func__' e '' item.im_self' con voce .__ self__' – lou
Potrebbe essere necessario '' def __eq __ (self, Altro): restituire altro() == self() ''? È il miglior modello di confronto? (e probabilmente '' __ne__'' come l'inverso) – Rafe