在Python中从一个字典的子字典中弱引用另一个字典的项目

0 投票
1 回答
935 浏览
提问于 2025-04-18 04:11

这个问题有点复杂,我尽量简单明了地解释一下。我现在有两个字典,dict1dict2dict1 包含了两个字典里的所有项目,而且它存储的是实际的对象,而不是对象的引用。另一个重要的点是,dict1 把所有的项目都放在了自己这个字典里。

dict2 则被分成了几个子字典,每个子字典里包含一个或多个来自 dict1 的项目,这样 dict1 中的所有对象也都在 dict2 的子字典的交集中,并且没有重复的项目。现在的问题是,我想对 dict2 的子字典里的项目做弱引用,这样当某个项目从 dict1 中删除时,dict2 的子字典中的引用也会被删除。

举个例子:

>>> import weakref
>>> dict1 = {}
>>> dict2 = {'subdict': {}}
>>> class Object: pass

>>> a = Object()
>>> a_ref = weakref.ref(a)
>>> dict1['a'] = a
>>> dict2['subdict']['a'] = a_ref
>>> del dict1['a']
>>> assert not dict2['subdict']['a']() # raises an assertion error

我该怎么做呢?用弱引用可以实现吗?我是不是误解了弱引用的用途?

1 个回答

1

为什么不把所有的子字典都做成WeakValueDictionary呢?这样的话,当dict1中唯一的强引用被移除时,WeakValueDictionary中的弱引用就会自动删除那个条目。

举个例子:

>>> class A: pass
... 
>>> import weakref
>>> d1 = {}
>>> d2 = {'sub': weakref.WeakValueDictionary()}
>>> d1['a'] = A()
>>> d2['sub']['a'] = d1['a']
>>> del d1['a']
>>> d2['sub']['a']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/weakref.py", line 56, in __getitem__
    o = self.data[key]()
KeyError: 'a'

在测试的时候,确保你没有意外地让某个局部变量或全局变量绑定到你的对象上(比如在你的例子中,a仍然是绑定到Object()实例的局部名称,这会让它一直存在)。你可以用del来删除这些名称(例如del a),以确保它们被清除。

撰写回答