我正在研究如何在Python中实现简单的回调功能。我认为我可以使用weakref.WeakSet来实现,但显然我还有些遗漏或误解。你可以在代码中看到,我首先尝试使用'ClassA'对象中回调方法的列表,但意识到这将使已添加到回调列表的对象保持活动状态。相反,我尝试使用weakref.WeakSet,但这也没有起作用(至少不是这种方式)。代码最后四行的注释解释了我想要发生的事情。
有人能帮助我吗?
from weakref import WeakSet
class ClassA:
def __init__(self):
#self.destroyCallback=[]
self.destroyCallback=WeakSet()
def __del__(self):
print('ClassA object %d is being destroyed' %id(self))
for f in self.destroyCallback:
f(self)
class ClassB:
def destroyedObjectListener(self,obj):
print('ClassB object %d is called because obj %d is being destroyed'%(id(self),id(obj)))
a1=ClassA()
a2=ClassA()
b=ClassB()
a1.destroyCallback.add(b.destroyedObjectListener)
#a1.destroyCallback.append(b.destroyedObjectListener)
print('destroyCallback len() of obj: %d is: %d'%(id(a1),len(a1.destroyCallback))) # should be 1
a2.destroyCallback.add(b.destroyedObjectListener)
#a2.destroyCallback.append(b.destroyedObjectListener)
print('destroyCallback len() of obj: %d is: %d'%(id(a2),len(a2.destroyCallback))) # should be 1
del a1 # Should call b.destroyedObjectListener(self) in its __del__ method
del b # should result in no strong refs to b so a2's WeakSet should automatically remove added item
print('destroyCallback len() of obj: %d is: %d'%(id(a2),len(a2.destroyCallback))) # should be 0
del a2 # Should call __del__ method
更新:基于被接受的答案的解决方案可以在github上找到:git@github.com:thgis/PythonEvent.git
getattr(callback, '__self__', None)
代替异常。 - Shital Shah