Detecting Updates on Arbitrary Objects

Paul Johnston paul.paj at gmail.com
Sat Mar 14 01:26:19 EDT 2009


Hi,

I would like to be able to install a code hook to detect updates on
arbitrary objects. To give some background, I'm writing a web widget
library, that uses request-local storage. If there's a mutable object
on a widget (a dict is common), I'd like any attempts to update the
dict to cause the dict to be cloned into request-local storage and the
update applied.

Now, I did have this working quite nicely for dict and list instances,
by subclassing dict and list, and overriding the write methods (or
most of them - __setitem__, __delitem__, append, etc.) When the dict/
list is added to the widget, it's replaced with a clone, using the
DictProxy/ListProxy subclass. (I realise Proxy may have been slightly
inaccurate as a name) However, sometimes a user needs to use a list-
like object that isn't a list, and this approach breaks down.

So, I think I need to do a real object proxy - a class that defers
almost all attributes to an inner instance that it stores, but
overrides a few. The following is my initial attempt, which almost
works, but I think there must be a better way. In particular, needing
to explicitly override __iter__ and __eq__ spells trouble - what about
__ne__, __gt__, etc. Also, is there a way to catch just any change,
rather than trying to know all the change methods. A way to do this
for arbitrary objects (not just dicts and lists) would be good too.

Any hints, tips, or pointers to docs online?

Thanks,

Paul


class GenericProxy(object):
    def __init__(self, obj):
        self._obj = obj
    def __getattr__(self, a):
        return getattr(self._obj, a)

    def __iter__(self):
        return self._obj.__iter__()
    def __eq__(self, x):
        return self._obj.__eq__(x)

    __setitem__ = _catch_modify('__setitem__')
    __delitem__ = _catch_modify('__delitem__')
    append = _catch_modify('append')
    insert = _catch_modify('insert')



More information about the Python-list mailing list