watching mutables?

Mark McEahern marklists at mceahern.com
Fri Sep 27 18:02:06 EDT 2002


Someone (I think Skip?) mentioned the possibility of using metaclasses.  The
OP has asked for a method that doesn't require modifying the original code.
This doesn't satisfy that request, but is interesting nonetheless (imho):

#!/usr/bin/env python

class Watched(type):

    def __new__(cls, cls_name, bases, classdict):
        # print "__new__(%s, %s, %s, %s)" % (cls, cls_name, bases,
classdict)
        def w_setattr(self, name, value):
            print "%s.__setattr__(%s, %s)" % (cls_name, name, value)
            bases[0].__setattr__(self, name, value)

        def w_setitem(self, i, el):
            print "%s.__setitem__(%s, %s)" % (cls_name, i, el)
            bases[0].__setitem__(self, i, el)

        def w_getitem(self, i):
            print "%s.__getitem__(%s)" % (cls_name, i)
            return bases[0].__getitem__(self, i)

        def w_getattribute(self, name):
            print "%s.__getattribute__(%s)" % (cls_name, name)
            return bases[0].__getattribute__(self, name)

        classdict['__setattr__'] = w_setattr
        classdict['__setitem__'] = w_setitem
        classdict['__getitem__'] = w_getitem
        classdict['__getattribute__'] = w_getattribute

        return type.__new__(cls, cls_name, bases, classdict)

class WatchedDict(dict):

    __metaclass__ = Watched

class WatchedList(list):

    __metaclass__ = Watched

l = []
l.append(1)

l = WatchedList()
l.append(1)

d = WatchedDict()
d['a'] = 1

print d['a']

**
Output:

WatchedList.__getattribute__(append)
WatchedDict.__setitem__(a, 1)
WatchedDict.__getitem__(a)
1





More information about the Python-list mailing list