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