我正在尝试存储一些方法回调,但是引用它会使绑定对象保持活动状态,所以我试图将弱参数保留给方法,但这似乎不可能?
所以
为什么我不能保持弱参考。方法(见下面的例子)
保留方法参考的最佳方法是什么?标准库中的任何东西?或者我将不得不保持功能和对象参考。分离
示例:
import weakref
class A(object):
def m(self): pass
a = A()
import weakref
class A(object):
def m(self): pass
a = A()
rm = weakref.ref(a.m)
print "is weak ref to method dead?",rm() is None
print "Q1. why can't i keep weakref to bound method?"
ra = weakref.ref(a)
m = a.m
print "delete object"
del a
print "is object dead?",ra() is None
print "delete method"
del m
print "is object dead?",ra() is None
print "Q2. hmmm so i am stuck i can't keep a ref as it stops the object from gc, but weakref to method isn't working?"
答案 0 :(得分:3)
由于该方法绑定到该对象,如果该对象不存在,您希望用它做什么?自己会包含什么?
如果您不需要方法中的对象,请将其设为classmethod。那么你的对象就是GC:d,即使你有一个方法的正常引用。
答案 1 :(得分:2)
Python Cookbook中的6.10节“在不禁止垃圾收集的情况下保留对绑定方法的引用”,提供了一个非常简洁的讨论和解决方案。您可以在线阅读(在Google图书上)here;我们把这个食谱归功于Knapka,Jolliton和Nicodemus(部分来自最初的另一个答案已经提到过的有效状态菜谱配方),当然,像在Cookbook中一样,我们(我,我的妻子Anna和David Ascher)是负责整个讨论流程和选择打印的确切代码版本,因此,如果出现问题,那就是我们的错误; - )。
答案 2 :(得分:0)
我问过the same question here!在我的问题中,我谈到GObject,但认识到它是任何类型的Python中的一般问题!我在那里得到了lioro的帮助,我在当前代码中使用的是下面的内容。一些要点:
您无法弱化方法对象。你必须弱化实例及其函数属性,或者只是方法名称(就像我在下面的代码中所做的那样)
您可以添加一些机制来在您的连接对象消失时取消注册回调,如果您不这样做,您将改为使用WeakCallback对象,并在偶数发生时执行空方法。
class WeakCallback (object):
"""A Weak Callback object that will keep a reference to
the connecting object with weakref semantics.
This allows object A to pass a callback method to object S,
without object S keeping A alive.
"""
def __init__(self, mcallback):
"""Create a new Weak Callback calling the method @mcallback"""
obj = mcallback.im_self
attr = mcallback.im_func.__name__
self.wref = weakref.ref(obj, self.object_deleted)
self.callback_attr = attr
self.token = None
def __call__(self, *args, **kwargs):
obj = self.wref()
if obj:
attr = getattr(obj, self.callback_attr)
attr(*args, **kwargs)
else:
self.default_callback(*args, **kwargs)
def default_callback(self, *args, **kwargs):
"""Called instead of callback when expired"""
pass
def object_deleted(self, wref):
"""Called when callback expires"""
pass
使用说明:
# illustration how I typically use it
weak_call = WeakCallback(self._something_changed)
long_lived_object.connect("on_change", weak_call)
我在子类中使用WeakCallback.token
属性来管理当连接器消失时断开回调
答案 3 :(得分:0)