可能重复:
为什么不';weakref没有研究这个定界方法吗?
一点上下文:
我试图实现一个Listener(或Observer,下同(模式:EventManager保存一个对事件感兴趣的所有Listener处理程序的列表。例如,Listener对象将有一个onEndOfTheWorldEvent
方法,每次发布事件类EndOfTheWorldEvent的实例时,EventManager都会调用该方法。容易的
除了我想弱引用处理程序之外,因为我不希望EventManager在不再需要Listener时保持我的处理程序(绑定方法(的活动状态。
所以我想"让我们把所有的处理程序都放在一个弱点集中"。我无法让它工作。
我在这里转储代码(或者当我将其减少到最小时剩下的代码,这里只有一种事件类型和一种处理程序类型(。
#! /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:键是侦听器本身,值是处理程序。事实上,我可以削弱我的听众。但它使数据结构变得有点复杂,当需要向每个人广播事件时,该结构中还有一个层次需要经历。
你觉得怎么样?
假设您想要一个方法"meth"上的weakrefs。
你可以像这个一样得到它的弱点
weak_obj = weakref.ref(meth.im_self)
weak_func = weakref.ref(meth.im_func)
所以,你可以像一样取消它
obj = weak_obj()
func = weak_func()
用取回"冰毒">
meth = getattr(obj, func.__name__)
listener.handler
每次都会为您提供一个新的函数绑定引用。因此,它几乎立即被收集垃圾。