可能是重复问题:
为什么该绑定方法无法使用弱引用?
一些背景信息:
我试图实现一个监听器模式(或者观察者模式):一个事件管理器维护了所有对事件感兴趣的监听器处理程序的列表。例如,一个监听器对象将会有一个onEndOfTheWorldEvent
方法,每当一个EndOfTheWorldEvent类的实例被发布时,该方法都会被事件管理器调用。很简单。
但是,我想要使用弱引用来引用处理程序,因为当不再需要监听器时,我不希望事件管理器保持我的处理程序(绑定方法)处于活动状态。
所以我想到“让我们把所有处理程序放在WeakSet中”。但我无法使其工作。
下面是代码(或者说是最小化后的代码,这里只有一种事件和一种处理程序):
#! /usr/bin/python
"""
"""
import sys
import weakref
class Listener(object):
def handler(self, event):
print event
class EventManager(object):
def __init__(self):
self.handlers = weakref.WeakSet()
def register(self, listener):
print "Registering..."
self.handlers.add(listener.handler)
CountRefs(listener.handler)
print "Number of handlers registered:", len(self.handlers)
print "Registered."
def CountRefs(what):
print "Hard count:", sys.getrefcount(what)
print "Weak count:", weakref.getweakrefcount(what)
listener = Listener()
em = EventManager()
CountRefs(listener.handler)
em.register(listener)
CountRefs(listener.handler)
结果:
Hard count: 3
Weak count: 0
Registering...
Hard count: 3
Weak count: 0
Number of handlers registered: 0
Registered.
Hard count: 3
Weak count: 0
看起来从来没有弱引用,集合始终为空。
为了让它更简单:
>>> class C(object):
>>> def blah(self):
>>> print "blah"
>>>
>>> c = C()
>>> w = weakref.ref(c.blah)
>>> print w
<weakref at 0x11e59f0; dead>
我能否完全无法创建方法的弱引用?如果不能,为什么?
所以我猜解决方法是用WeakKeyDictionary代替WeakSet:键是监听器本身,值是处理程序。事实上,我可以弱引用我的Listeners。但这使得数据结构变得有点复杂,并且在广播事件给所有人时,需要经过该结构中的另一个层次。
你认为呢?