frozendict (v0.1)
Arnaud Delobelle
arnodel at gmail.com
Thu Oct 7 18:41:34 EDT 2010
Oops I sent off my reply before I had finished!
kj <no.email at please.post> writes:
> Following a suggestion from MRAB, I attempted to implement a
> frozendict class. My implementation took a lot more work than
> something this simple should take, and it still sucks. So I'm
> hoping someone can show me a better way. Specifically, I'm hoping
> that there is a "recipe" for building off standard classes that
> cover all the bases with a minimum of tedious repetitive work.
>
> Here's my little monster:
>
> ass frozendict():
> _DESTRUCTIVE = set(('__delitem__ __setitem__ clear pop popitem setdefault '
> 'update').split())
[...]
> def __hash__(self):
> return hash(tuple(self.items()))
Also, you'll probably want to cache your hash value.
>
>
> def __getattr__(self, attrib):
> class_ = self.__class__
> dict_ = self._dict
> if attrib in class_._COMPARISONS:
> return lambda x: dict_.__getattribute__(attrib)(x._dict)
> elif attrib in class_._NON_DESTRUCTIVE:
> return dict_.__getattribute__(attrib)
> else:
> if attrib in class_._DESTRUCTIVE:
> raise TypeError("'%s' object is not mutable" % class_.__name__)
> else:
> raise AttributeError("'%s' object has no attribute '%s'" %
> (class_.__name__, attrib))
>
>
>
> I didn't implement this as a subclass of dict to avoid having to
> write a dumb little "blocking" method for every destructive dict
> method. (I couldn't figure out how to write a loop to define these
> overriding methods programmatically, because their signatures are
> all over the place.)
You could subclass dict and have something like:
class frozendict(dict):
DESTRUCTIVE = ...
for meth in DESTRUCTIVE:
exec """def %s(s, *a, **k): raise TypeError("not mutable")"""
del DESTRUCTIVE
...
--
Arnaud
More information about the Python-list
mailing list