Observer-Pattern by (simple) decorator

Wildemar Wildenburger wildemar at freakmail.de
Sat Jun 2 17:44:30 CEST 2007


Peter Otten wrote:
> Then you have modified the code posted by Steven Bethard.
>
>   
Oops. Indeed I did.
I changed this

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


to this

>>> class Observable(object):
...     def __init__(self, func, instance=None, observers=None):
...         self.func = func
...         self.instance = instance
...         self.observers = observers or []


>> I don't see how your behaviour should come about ... a new observer-list
>> is created for every decorated method, so there is no problem.
>>     
>
> Yes, but that list is shared across instances of SomeActor.
>   
Oh! I thought a new Observable-object is created for every *instance* of 
SomeActor, where there is actually only one Observable per method that 
decorates *all* methods (all meth() methods, that is). Am I right?

And I seem to have accidentally "solved" this by rewriting the 
__init__() method the way I did. Now it creates a new list even when it 
gets passed an empty list. How very smart of me ... ;)

Looking at the way it is going to be used, I don't see a problem with 
this. Or am I missing something that could stab me in the back here?


Thanks for the thorough explanation. But you *did* mock me with that 
"SomeActor.meth is SomeActor.meth"-line, right? ;)

>
> If you want per-instance callbacks you have to store the observers list (or
> the bound method) in the instance:
>
>   
>>>> class SomeActor(object):
>>>>         
> ...     def __init__(self):
> ...             self.meth = Observable(self.meth, self)
> ...     def meth(self, foo): print foo
>   
Seems good, but I'm trying to take as much hassle out of the programmer 
(probably me, mostly) as possible in order to watch method calls. Simply 
sticking a decorator in front of a methos, with no arguments, no 
nothing, seems less prone to errors.
Also, reading "self.meth = Observable(self.meth, self)" kinda makes 
sense now, but I *know* I'd be scratching my head about this in no less 
than a few weeks. BTW, that might be my single favorite line of python 
code so far ... :)

/W



More information about the Python-list mailing list