Observer pattern thoughts

george young gry at ll.mit.edu
Thu Mar 6 21:42:32 CET 2003


I'm using an observer pattern as part of a model-view-presenter/controller GUI
app.  I had simply grabbed someone's source file with observer/observable 
classes and crunched along, inheriting from these classes and using register,
notify, etc.  But it seems to me that the classic Observable (adapted from
type-anal C++):

class Observable:
    def __init__(self):
        self.observers = []
    def register(self, o):
        self.observers.append(o)
    def un_register(self, o):
        self.observers.remove(o)
    def notify(self):
        for o in self.observers:
            o.update(self)

class Myobservable(Observable):
    whatever...

class Myobserver:
    def update(selfm model):
        self.crunchnewvalue(model.get())
    def __init__(self):
        mo = myobservable()
        mo.register(self)

is unnecessarily restrictive and inflexible for python code.
Why require an observer to
  observable.register(self)
and define a member update(self), when it seems like the observable
could just take a callable object and call it:

class NewObservable:
    ....
    def notify(self):
        for o in self.observers:
            o()

ob = myobserverclass()
ob.register(ob.somefunc)

This scheme keeps the simplest interface, but allows one observer to
have as many different observables as wanted, with different update
functions.  Or one update func with different attributes via a lamda curry:

ob1.register(lambda :ob.func(someval))
ob2.register(lambda :ob.func(otherval))

Am I missing something?  Am I still suffering from C++ toxicity after
two years of pythonic bliss?

-- George
-- 
 I cannot think why the whole bed of the ocean is
 not one solid mass of oysters, so prolific they seem. Ah,
 I am wandering! Strange how the brain controls the brain!
	-- Sherlock Holmes in "The Dying Detective"




More information about the Python-list mailing list