循环引用不调用弱引用回调
作者:互联网
我正在尝试为具有循环引用的Python类编写终结器.我发现弱引用回调是way to go.不幸的是,似乎从未调用过用作回调的lambda.例如,运行以下代码:
def del_A(name):
print('An A deleted:' + name)
class A(object):
def __init__(self, name):
print('A created')
self.name = name
self._wr = weakref.ref(self, lambda wr, n = self.name: del_A(n))
class B(object):
def __init__(self):
print('B created')
if __name__ == '__main__':
a = A('a1')
b = B()
a.other = b
b.other = a
返回:
A created
B created
删除循环引用将使lambda回调起作用(打印“ An A Deleted:a1”).也可以通过简单的函数调用替换lambda,但是在初始化弱引用时(而不是在调用回调时)参数值是固定的:
self._wr = weakref.ref(self, del_A(self.name))
...
a = A('a1')
a.name = 'a2'
b = B()
a.other = b
b.other = a
返回:
A created
An A deleted:a1
B created
知道为什么lambda回调不适用于循环引用吗?
解决方法:
使用时
self._wr = weakref.ref(self, lambda wr, n = self.name: del_A(n))
仅在self将要完成时才调用回调.
回调未得到调用的原因是
a = A('a1')
b = B()
a.other = b # This gives a another attribute; it does not switch `a` away from the original `a`
b.other = a
不会导致定案.原始的a仍然存在.
如果将代码更改为,则将调用回调
a = A('a1')
b = B()
a = b
b = a
使用时
self._wr = weakref.ref(self, del_A(self.name))
那么您的回调为无. del_A(self.name)不是对函数的引用,它是函数本身.因此,del_A(self.name)立即打印出一个A Deleted:a1(在a1最终确定之前),并返回值None,这成为weakref的默认回调.
标签:weak-references,python,lambda 来源: https://codeday.me/bug/20191106/2001241.html