Kent Johnson wrote: > I'm curious about why you want to do this, it is kind of a strange > requirement. But anyway, here is a class that subclasses dict and > presents the interface you want to client code. It doesn't actually > update all instances when you add or delete a key; it keeps a list of > valid keys in a class attribute and updates this list when you add or > delete. Then when you access a key it checks the list of valid keys. > If the key you want is not in the list, you get a KeyError - the > instance dict is never checked. If the key you want is in the list > but not in the instance, you get the default value.
This class needs a little more work to correctly model a dictionary - its keys(), values(), items(), __contains__(), __iter__() and iteritems() methods at least need customization to work from the _keys attribute. One way to do this would be to inherit from UserDict.DictMixin; then only keys() would have to be defined. Kent > I don't see any need to actually add default values to all the dicts. > Conceivably to save memory you might want to actually delete values > from all the dicts; to do this you could keep a list of all the > existing dicts as another class attribute. I'm not sure you will save > much though as the dict itself probably doesn't resize downward. A > side effect of not deleting keys is that if you delete and then > restore a key, instances that had that key before will magically > restore their old value. This could be a bug or a feature depending > on your requirements. > > Finally, the set of valid keys is shared by all instances, so if you > want to use this for two different types of things you will have to > make subclasses and give each subclass its own _key attribute.> > Requires Python 2.3 or greater > > Kent > > # CommonKeysDict.py > # Make it work with Python 2.3 > try: > set > except NameError: > from sets import Set as set > > class CommonKeysDict(dict): > """Dictionary where all instances must have the same set of keys > and with a default value for unknown keys. > > >>> d = CommonKeysDict() > >>> d[0] > Traceback (most recent call last): > ... > KeyError: 0 > > >>> d[0] = 1 > >>> d[0] > 1 > > A second instance will get the default value for keys that are in use: > >>> d2 = CommonKeysDict() > >>> d2[0] > 'default' > > The second instance can have its own values > >>> d2[0] = 2 > >>> d2[0] > 2 > >>> d[0] > 1 > > Deleting a key from any instance removes that key from the allowed set. > Note that this doesn't actually delete the key from all instances, it > just > makes it inaccessible. > > >>> del d[0] > >>> d2[0] > Traceback (most recent call last): > ... > KeyError: 0 > > """ > > _keys = set() > > def __init__(self, **items): > dict.__init__(self, **items) > > def __getitem__(self, key): > if key not in self._keys: > raise KeyError, key > try: > return dict.__getitem__(self, key) > except KeyError: > return 'default' > > > def __setitem__(self, key, value): > self._keys.add(key) > dict.__setitem__(self, key, value) > > > def __delitem__(self, key): > self._keys.remove(key) > dict.__delitem__(self, key) > > > def _test(): > import doctest > doctest.testmod() > > if __name__ == "__main__": > _test() > > > _______________________________________________ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor > > _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor