Event handling in python

Update: for the latest code please check nevent.py in the legume google code repository

Typically, event handling in python either involves storing a function pointer and invoking it at some pointer later-on, or inheriting a base-class and overriding event handler stubs. Storing a single function pointer does not permit event handler chaining, but is the easiest method to expand upon, and acts as a replacement for event handler stubs in classes.

Expected usage of the Event handler:

def example_handler(param):
    print "1", param

example_event= Event()
example_event += example_handler
example_event('Hello!')

And the output:

1 Hello!
2 Hello!

A basic structure to the event handler class is shown below:

class EventError(Exception): pass

class Event(object):
    def __init__(self):
        self._handlers = []

    def __iadd__(self, other):
        if other not in self._handlers:
            self._handlers.append(other)
        else:
            raise EventError, \
                   'Event %s error: Handler %s is already bound' \
                   % (self, other)
        return self

    def __isub__(self, other):
        try:
            self._handlers.remove(other)
        except IndexError, e:
            raise EventError, \
                   'Event %s error: Handler %s is not bound' \
                   % (self, other)
        return self

    def __call__(self, sender, args):
        result = None
        for handler in self._handlers:
            result = handler(sender, args)
        return result

    def is_handled_by(self, handler):
        return handler in self._handlers

Note how overriding __iadd__ provides a syntax identical to C# for adding extra handlers onto the event handler chain – marvelous.

This code is actually based off the event handling used in the legume network library, see
nevent.py in the legume google code repository for the code in use, and to see any further changes.

 

Leave a Reply

Your email address will not be published. Required fields are marked *