سؤال

This is a bit of a complicated question setup but I'll explain it best I can. I'm in a situation where I have two dictionaries, dict1 and dict2. dict1 contains every item in both dictionaries, but it keeps the actual objects (and not a reference to the objects). Another important factor is that dict1 stores all the items in one dictionary; itself.

dict2 however is partitioned up into subdicts, each subdict containing one or more items from dict1 such that all the objects in dict1 are also in the intersection of the subdicts of dict2 and there are no duplicates. Now the problem is that I want to make weak references to the items in the dict2's subdicts such that when the item is deleted from the dict1, so is it's reference in the subdict of dict2.

For example:

>>> 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

How might I go about doing this? Is it even possible with weakrefs? Am I misinterpreting the purpose of weakrefs?

هل كانت مفيدة؟

المحلول

Why don't you make all of the subdictionaries WeakValueDictionarys? Then, when the only strong reference in dict1 is removed, the weakref in the WeakValueDictionary will cause that entry to be deleted automatically.

Example:

>>> 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'

Be sure that during your testing you don't accidentally have a local or global variable bound to your object (e.g. in your example, a is still a local name bound to the Object() instance, which will keep it alive). You can del names (e.g. del a) to ensure they are cleared.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top