frozendict (v0.1)

kj no.email at please.post
Thu Oct 7 17:39:07 EDT 2010











































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())

    _NON_DESTRUCTIVE = set(('__contains__ __format__ __getitem__ __hash__ '
                            '__init__ __iter__ __len__ __repr__ __sizeof__ '
                            '__str__ copy fromkeys get has_key items iteritems '
                            'iterkeys itervalues keys values'.split()))

    _COMPARISONS = set(('__cmp__ __eq__ __ge__ __gt__ __le__ __lt__ '
                        '__ne__').split())


    def __init__(self, iterable=(), **kwargs):
        self._dict = dict(iterable, **kwargs)


    def __hash__(self):
        return hash(tuple(self.items()))


    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.)

I didn't implement it as a subclass of object with an internal dict
delegate, because I couldn't figure a reasonable way to pass certain
object methods to the delegate (since in this case frozendict.__getattr__
wouldn't be called).

The handling of comparison methods is particularly horrific and
inefficient.

If "Beautiful is better than ugly", I sure how there's another way
that is a lot more beautiful than this one.

TIA!

~kj




More information about the Python-list mailing list