gpt4 book ai didi

python - 如果我在 Python 中有一个绑定(bind)方法的引用,仅此一项就能使对象保持事件状态吗?

转载 作者:太空狗 更新时间:2023-10-29 21:03:32 24 4
gpt4 key购买 nike

我今天写了这样的东西(与 mpl_connect 文档不同:

class Foo(object):
def __init__(self): print 'init Foo', self
def __del__(self): print 'del Foo', self
def callback(self, event=None): print 'Foo.callback', self, event


from pylab import *
fig = figure()
plot(randn(10))
cid = fig.canvas.mpl_connect('button_press_event', Foo().callback)
show()

这看起来很合理,但它不起作用——就好像 matplotlib 忘记了我给它的函数一样。如果不是通过它 Foo().callback我通过了lambda e: Foo().callback(e) , 有用。同样,如果我说 x = Foo()然后传递它 x.callback , 它有效。

我的假设是 Foo() 创建的未命名 Foo 实例在 mpl_connect 之后立即销毁行——具有 Foo.callback 的 matplotlib引用不保留 Foo活。那是对的吗?

在我遇到这个的非玩具代码中,x = Foo()的解决方案没有用,大概是因为在那种情况下 show()在别处所以x超出了范围。

更一般地说,Foo().callback<bound method Foo.callback of <__main__.Foo object at 0x03B37890>> .我最惊讶的是,绑定(bind)方法似乎实际上并未保留对该对象的引用。对吗?

最佳答案

是的,绑定(bind)方法引用对象 - 对象是绑定(bind)方法对象的 .im_self 属性的值。

所以我想知道 matplotlibmpl_connect() 是否记得增加传递给它的参数的引用计数。如果不是(这是一个常见错误),那么当 mpl_connect() 返回时,没有什么可以让匿名 Foo().callback 保持事件状态。

如果您可以轻松访问源代码,请查看mpl_connect() 实现?你想看到 C 代码执行 Py_INCREF() ;-)

编辑 这看起来很相关,from docs here :

The canvas retains only weak references to the callbacks. Therefore if a callback is a method of a class instance, you need to retain a reference to that instance. Otherwise the instance will be garbage- collected and the callback will vanish.

所以这是的错 - 哈哈 ;-)

关于python - 如果我在 Python 中有一个绑定(bind)方法的引用,仅此一项就能使对象保持事件状态吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19556123/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com