Nach der Dokumentation für das WeakRef Modul:
Im Folgenden bedeutet der Begriff referent das Objekt, das zu durch eine schwache Referenz bezeichnet wird.
Ein schwacher Verweis auf ein Objekt ist nicht genug, um das Objekt am Leben zu halten: wenn der einzigen verbleibenden Verweis auf einen referenten sind schwache Verweise, Müll Sammlung den referenten zu zerstören frei ist und seine Erinnerung wieder verwendet für etwas anderes.
Was ist mit MyCallbackA passiert ist, dass Sie in den Instanzen A, dank einen Verweis darauf halten -
self.MyCallbackA = MyCallbackA
Jetzt gibt es keinen Hinweis auf die gebundene Methode MyCallbackB in Ihrem Code. Es wird nur in einer .__ Klasse __.__ dict__ als ungebundene Methode gehalten. Im Grunde wird eine gebundene Methode erstellt und zurückgegeben, wenn Sie self.methodName ausführen. (AFAIK, eine gebundene Methode funktioniert wie eine Eigenschaft - unter Verwendung eines Deskriptors (schreibgeschützt): zumindest für neue Stilklassen. Ich bin mir sicher, etwas Ähnliches, dh ohne Deskriptoren passiert für alte Stilklassen. Ich überlasse es Jemand, der erfahrener ist, um die Behauptung über alte Stilklassen zu überprüfen.) So stirbt self.MyCallbackB, sobald die Schwachstelle erzeugt wird, weil es keinen starken Bezug darauf gibt!
sind meine Schlussfolgerungen basieren auf: -
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()
Ausgabe
erstellen MyCallbackB
Del MycallbackB
MyCallbackA
0 mit MyCallbackB Geschehen spielen
Hinweis:
Ich habe versucht, dies für alte Klassen zu überprüfen. Es stellte sich heraus, dass "Druck a.test_a .__ get__" Ausgänge -
<method-wrapper '__get__' of instancemethod object at 0xb7d7ffcc>
für den neuen und alten Stil-Klassen. Es kann also nicht wirklich ein Deskriptor sein, nur ein Deskriptor. In jedem Fall besteht der Punkt darin, dass ein gebundenes Methodenobjekt erstellt wird, wenn Sie eine Instanzmethode über self aufrufen, und es wird gelöscht, sofern Sie nicht einen starken Verweis darauf beibehalten.
für Python 3 ersetzen 'item.im_func' mit' Artikel .__ func__' und 'item.im_self' mit' Artikel .__ self__' – lou
Möglicherweise müssen '' def __eq __ (self, andere): return andere() == self() ''? Ist das das beste Vergleichsmuster? (und wahrscheinlich '' __ne__'' als Inverse) – Rafe