Advertisement
Guest User

WeakKeyIDDictionary simple implementation

a guest
Dec 30th, 2014
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.71 KB | None | 0 0
  1. import collections.abc as cabc
  2. import weakref
  3.  
  4.  
  5. class WeakKeyIDDictionary(cabc.MutableMapping):
  6.     def __init__(self):  # TODO: Allow passing parameters here
  7.         self._ids = weakref.WeakValueDictionary()  # from id(key) to key
  8.         self._values = {}  # from id(key) to value
  9.  
  10.     def _remove_dead_refs(self):
  11.         """Remove items from self._values which are not in self._ids.
  12.  
  13.        Return true if the dictionary changed.
  14.  
  15.        """
  16.         strong_ids = list(self._ids.values())  # hold strong references to
  17.                                                # keep the dictionary stable
  18.         dead_identifiers = self._values.keys() - self._ids.keys()
  19.         for identifier in dead_identifiers:
  20.             del self._values[identifier]
  21.         return bool(dead_identifiers)
  22.  
  23.  
  24.     def __getattr__(self, key):
  25.         # We have a strong reference to key, so it won't vanish.
  26.         # Calling _remove_dead_refs() would not affect the correctness of this
  27.         # method.
  28.         identifier = id(key)
  29.         return self._values[identifier]
  30.  
  31.     def __setattr__(self, key, value):
  32.         # We have a strong reference to key, so again it won't vanish.
  33.         identifier = id(key)
  34.         self._ids[identifier] = key
  35.         self._values[identifier] = value
  36.  
  37.     def __delattr__(self, key):
  38.         # Strong reference, won't vanish.
  39.         del self._ids[identifier]
  40.         del self._values[identifier]
  41.  
  42.     def __iter__(self):
  43.         for identifier, key in self._ids.items():
  44.             # Have a strong ref to key
  45.             # And the dictionary isn't allowed to change during iteration
  46.             # anyway
  47.             yield key
  48.    
  49.     def __len__(self):
  50.         return len(self._ids)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement