2

我正在尝试存储一些方法回调,但引用它会使绑定的对象保持活动状态,所以我试图为方法保留一个弱引用,但这似乎不可能?

所以

  • 为什么我不能保持弱参考。to 方法(见下面的例子)

  • 保持方法参考的最佳方法是什么?标准库中有什么东西吗?否则我将不得不保留函数和对象引用。分离?

例子:

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?"
4

4 回答 4

3

由于方法绑定到对象,如果对象不存在,您希望用它做什么?什么会自包含?

如果您不需要方法中的对象,请将其设为类方法。然后,即使您对该方法有正常的引用,您的对象也将是 GC:d。

于 2009-11-04T12:35:02.240 回答
2

Python Cookbook 中的 6.10 节“保持对绑定方法的引用而不禁止垃圾回收”提供了一个相当彻底但简洁的讨论和解决方案。您可以在此处在线阅读(在 Google 图书上) ;我们将这个食谱归功于 Knapka、Jolliton 和 Nicodemus(部分来自另一个答案已经提到的原始 activestate 食谱食谱)当然,就像食谱中的往常一样,我们(我、我的妻子 Anna 和 David Ascher)是负责整个讨论流程和选择打印的确切代码版本的人,所以,如果这些有问题,那是我们的错;-)。

于 2009-11-04T15:52:07.703 回答
0

我在这里问过同样的问题!在我的问题中,我谈到了 GObject,但认识到它在任何类型的 Python 中都是一个普遍问题!我在那里得到了 lioro 的帮助,我在当前代码中使用的内容如下。一些重要的点:

  • 您不能对方法对象进行弱引用。您必须弱引用实例及其函数属性,或者只是方法名称(就像我在下面的代码中所做的那样)

  • 您可以添加一些机制来在您连接的对象消失时取消注册回调,如果您不这样做,您将使用 Wea​​kCallback 对象,并在事件发生时执行一个空方法。

.

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在子类中使用属​​性来管理当连接器消失时断开回调

于 2009-11-04T13:55:23.927 回答
0

他们有一个很好的解决方案:

http://code.activestate.com/recipes/81253/

看看 Anonymous 发布的最后一个示例。

于 2009-11-04T14:22:59.463 回答