We're back after a server migration that caused effbot.org to fall over a bit harder than expected. Expect some glitches.

Simple Observer

Updated February 19, 2003 | Fredrik Lundh

The Observable class is a simple mixin class which can be used to make container objects “observable”. An observable container issues events when being modified, and external “observers” can subscribe to such events.

For a more advanced event dispatching library, see PyDispatcher.

The Observable Mixin Class
class Observable:

    __observers = None

    def addobserver(self, observer):
        if not self.__observers:
            self.__observers = []
        self.__observers.append(observer)

    def removeobserver(self, observer):
        self.__observers.remove(observer)

    def notify(self, event, data=None):
        for o in self.__observers or ():
            o(event, data)

Usage

To use this class, you can simply inherit from it:

class Model(Observable):

    def append(self, data):
        self.notify("update")

class Viewer:

    def __init__(self, model):
        self.model = model
        self.model.addobserver(self.handle_notification)

    def __del__(self, model):
        self.model.removeobserver(self.handle_notification)

    def handle_notification(self, event, data):
        ...

You can also use multiple inheritance to turn an existing model class into an observable object:

class StorageModel(Storage, Observable):

    def insert(self, data):
        Storage.insert(self, data) # delegate
        self.notify("addrecord", data) # notify

Methods

addobserver(observer)

The addobserver method adds an observer object to the container. The observer should be a callable object which takes two arguments (the event code and associated data).

removeobserver(observer)

The removeobserver method removes the given observer object from the container. The observer must exist.

notify(event, data)

The notify method sends an event and associated data to all observers. If the data argument is omitted, None is used instead.

The event can be any kind of object, but is usually an integer constant or an instance of an event class hierarchy (which allows the observer to use isinstance to check for event categories).

If an observer raises an exception, it’s undefined (by the interface, not by this specific implementation) whether any other observers will be called. The exception itself is propagated back to the caller.