TL;医生
是否有任何方法可以创建一个弱引用,在留下1个强引用而不是0时调用回调?
对于那些认为这是x y问题的人来说,下面是一个很长的解释:
我有一个非常具有挑战性的问题,我正试图用我的代码来解决。
假设我们有一个类foo的实例,以及一个不同的类栏,它在使用实例时引用该实例:
class Foo: # Can be anything
pass
class Bar:
"""I must hold the instance in order to do stuff"""
def __init__(self, inst):
self.inst = inst
foo_to_bar = {}
def get_bar(foo):
"""Creates Bar if one doesn't exist"""
return foo_to_bar.setdefault(foo, Bar(foo))
# We can either have
bar = get_foobar(Foo())
# Bar must hold a strong reference to foo
# Or
foo = Foo()
bar = get_foobar(foo)
bar2 = get_foobar(foo) # Same Bar
del bar
del bar2
bar3 = get_foobar(foo) # Same Bar
# In this case, as long as foo exists, we want the same bar to show up,
# therefore, foo must in some way hold a strong reference back to bar
现在有一个棘手的部分:您可以使用循环引用来解决这个问题,其中
foo
参考文献
bar
和
酒吧
参考文献
FOO公司
但是,嘿,其中有什么有趣的部分?如果foo定义的话,清理时间会更长,不会起作用。
__slots__
一般来说,这是一个糟糕的解决方案。
有没有办法,我可以创建一个
foo_to_bar
映射在
单一的
对两者的引用
FOO公司
和
酒吧
是吗?本质上:
import weakref
foo_to_bar = weakref.WeakKeyDictionary()
# If bar is referenced only once (as the dict value) and foo is
# referenced only once (from bar.inst) their mapping will be cleared out
这样它就可以像
FOO公司
在功能之外确保
酒吧
还在吗(我可能需要
_插槽__
在
Foo
支持
__weakref__
)并且拥有
酒吧
在函数外部导致
FOO公司
仍然在那里(因为在
Bar
)。
WeakKeyDictionary
不工作,因为
{weakref.ref(inst): bar.inst}
将导致循环引用。
或者,是否有任何方法可以钩住引用计数机制(以便在两个对象都达到1个引用时进行清理),而不会产生大量开销?