[ZODB-Dev] Dynamic Wrapper?

Chris Spencer gmane.20.evilspam at spamgourmet.com
Thu Dec 15 20:12:54 EST 2005


Instead of requiring all persistable objects to inherit a special class, 
wouldn't it be possible to dynamically wrap a class's __setattr__ and/or 
__setitem__ methods to determine when an object's been modified? 
Something like:

class Monitor(object):

     class Proxy(object):
         def __init__(self, obj):
             self.obj = obj
         def __hash__(self):
             return id(self.obj)
         def __cmp__(self, p):
             return cmp(id(self.obj),id(p.obj))

     def __init__(self):
         self.modified = set()

     def add(self, obj):
         def newSetter(func):
             def registerChanges(theirself, *args, **kwargs):
                 self.modified.add(self.Proxy(theirself))
                 return func(theirself, *args, **kwargs)
             return registerChanges
         if hasattr(obj, '__setattr__'):
             obj.__class__.__setattr__ = 
newSetter(obj.__class__.__setattr__)
         if hasattr(obj, '__setitem__'):
             obj.__class__.__setitem__ = 
newSetter(obj.__class__.__setitem__)

m = Monitor()

from UserDict import UserDict
d = UserDict()
m.add(d)
d[123] = 'abc'

print m.modified
 >>> set([<__main__.Proxy object at 0xb7f28acc>])

I understand this has some drawbacks. Namely, it will only work for 
new-style classes, but for a large code base this might be easier than 
manually writing _p_changed = 1 everywhere.

Chris



More information about the ZODB-Dev mailing list