[Tutor] Prevent "Coder's Remorse"?
Kent Johnson
kent37 at tds.net
Thu Sep 29 11:49:42 CEST 2005
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 at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
>
More information about the Tutor
mailing list