Wildemar Wildenburger wrote: > I thought: I'll just write a decorator that lets me react to method > calls easily (the ever so popular observer-pattern). I've looked at some > recepies, but I just don't get them (I'm feeling kinda dumb today, sorry). [snip] > This is more complicated than expected mainly for two reasons: > > * I can't find a way to pass the proper 'instance' argument to > callback, that is, I don't know how to retrieve the instance that > meth() was called on, because the observable decorator only gets > the *function* object but not the *method*. (I hope this was clear > enough) > * Also, I don't see how I could add the add_callback() method to the > meth object. That doesn't seem possible. I can add it to meth's > function object just fine in the definition of observable, but I > thats not what I really want. This is probably just a cosmetic > issue because I don't like the idea of calling > sa.meth.im_func.add_callback(callback).
I think you want to define __get__ on your Observable class so that it can do the right thing when the method is bound to the instance: >>> class Observable(object): ... def __init__(self, func, instance=None, observers=None): ... if observers is None: ... observers = [] ... self.func = func ... self.instance = instance ... self.observers = observers ... def __get__(self, obj, cls=None): ... if obj is None: ... return self ... else: ... func = self.func.__get__(obj, cls) ... return Observable(func, obj, self.observers) ... def __call__(self, *args, **kwargs): ... result = self.func(*args, **kwargs) ... for observer in self.observers: ... observer(self.instance) ... return result ... def add_callback(self, callback): ... self.observers.append(callback) ... >>> class SomeActor(object): ... @Observable ... def meth(self, foo): ... print foo ... >>> def callback(instance): ... print "Yippie, I've been called on", instance ... instance.bar = True ... >>> sa = SomeActor() >>> sa.meth.add_callback(callback) >>> sa.meth("I'm the boring old argument") I'm the boring old argument Yippie, I've been called on <__main__.SomeActor object at 0x00E7A4D0> >>> sa.bar True STeVe -- http://mail.python.org/mailman/listinfo/python-list