Observer pattern thoughts

Andrew Bennetts andrew-pythonlist at puzzling.org
Fri Mar 7 06:48:16 EST 2003


On Fri, Mar 07, 2003 at 09:49:00AM +0000, Tim Evans wrote:
> 
> The only thing that you might be missing is that you are not going far
> enough.  Rather than requiring lambdas to pass arguments, harness even
> more of Python's dynamic nature and use this:
> 
> class NewObservable:
>     def __init__(self):
>         self.observers = []
> 
>     def register(self, func, *args, **kw):
>         self.observers.append((func, args, kw))
> 
>     def notify(self):
>         for func, args, kw in self.observers:
>             func(*args, **kw)
> 
> # meanwhile, in a class on the other side of town:
>    ob1.register(self.method, someval)
>    ob2.register(self.method, otherval)
> 
> Working out how to write un_register is left as an excercise for the
> reader.

I'd be tempted to do the unregister function like this:


class RegisteredFunc:
    def __init__(self, func, args, kwargs, observable):
        self.func = func
        self.args = args
        self.kwargs = kwargs
        self.observable = observable
   
    def unregister(self):
        observable.observers.remove(self)

class NewNewObservable:
    def __init__(self):
        self.observers = []
    
    def register(self, func, *args, **kwargs):
        rf = RegisteredFunc(func, args, kwargs, self)
        self.observers.append(rf)
        return rf

    def notify(self):
        for rf in self.observers:
            rf.func(*rf.args, **rf.kwargs)


I'm posting this because I suspect this idea (returning a handle to the
registered function from NewNewObservable.register) might not be immediately
obvious, but I find it is a very nice abstraction.  When I first saw this
idea (in Twisted, I think), I went "Oh!  What a good idea," so now I'm
sharing it :)

-Andrew.






More information about the Python-list mailing list