我可以弱参考方法吗



可能重复:
为什么不';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每次都会为您提供一个新的函数绑定引用。因此,它几乎立即被收集垃圾。

最新更新