您不能创建对方法对象的弱引用。方法对象是 短暂的 ;
它们是在您访问实例上的名称时动态创建的。请参阅描述符howto的工作原理。
当您访问方法名称时,将为您创建一个 新的 方法对象,然后将该方法添加到中
WeakSet,不再有对其的其他引用,因此垃圾回收很高兴再次对其进行清理。
您将不得不存储一些不太瞬变的东西。存储实例对象本身可以工作,然后在已注册的回调中调用预定义方法:
def __del__(self): for f in self.destroyCallback: f.destroyedObjectListener(self)
并注册:
a1.destroyCallback.add(b)
您还可以通过给它一个方法使
b自己 成为可调用的
__call__:
class ClassB: def __call__(self,obj): print('ClassB object %d is called because obj %d ' 'is being destroyed' % (id(self), id(obj)))另一种方法是存储对基础函数对象的引用以及对实例的引用:
import weakrefclass ClassA: def __init__(self): self._callbacks = [] def registerCallback(self, callback): try: # methods callback_ref = weakref.ref(callback.__func__), weakref.ref(callback.__self__) except AttributeError: callback_ref = weakref.ref(callback), None self._callbacks.append(callback_ref) def __del__(self): for callback_ref in self._callbacks: callback, arg = callback_ref[0](), callback_ref[1] if arg is not None: # method arg = arg() if arg is None: # instance is gone continue callback(arg, self) continue else: if callback is None: # callback has been deleted already continue callback(self)
演示:
>>> class ClassB:... def listener(self, deleted):... print('ClassA {} was deleted, notified ClassB {}'.format(id(deleted), id(self)))... >>> def listener1(deleted):... print('ClassA {} was deleted, notified listener1'.format(id(deleted)))... >>> def listener2(deleted):... print('ClassA {} was deleted, notified listener2'.format(id(deleted)))... >>> # setup, one ClassA and 4 listeners (2 methods, 2 functions)... >>> a = ClassA()>>> b1 = ClassB()>>> b2 = ClassB()>>> a.registerCallback(b1.listener)>>> a.registerCallback(b2.listener)>>> a.registerCallback(listener1)>>> a.registerCallback(listener2)>>> >>> # deletion, we delete one instance of ClassB, and one function... >>> del b1>>> del listener1>>> >>> # Deleting the ClassA instance will only notify the listeners still remaining... >>> del aClassA 4435440336 was deleted, notified ClassB 4435541648ClassA 4435440336 was deleted, notified listener2


