在Python中从一个字典的子字典中弱引用另一个字典的项目
这个问题有点复杂,我尽量简单明了地解释一下。我现在有两个字典,dict1
和 dict2
。dict1
包含了两个字典里的所有项目,而且它存储的是实际的对象,而不是对象的引用。另一个重要的点是,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
),以确保它们被清除。