



  

Events 0.3 documentation

 [Events](index.html#document-index) 

 stable

 

[Events](index.html#document-index)

* [Docs](index.html#document-index) »

* Events 0.3 documentation

* [Edit on GitHub](https://github.com/pyeve/events/blob/3857d0ce91cd4869a00d49da38ce033e9b174476/docs/index.rst)

---

Events[¶](#events "Permalink to this headline")

===============================================

*Bringing the elegance of C# EventHandler to Python*

The concept of events is heavily used in GUI libraries and is the foundation

for most implementations of the MVC (Model, View, Controller) design pattern.

Another prominent use of events is in communication protocol stacks, where

lower protocol layers need to inform upper layers of incoming data and the

like. Here is a handy class that encapsulates the core to event subscription

and event firing and feels like a “natural” part of the language.

The package has been tested under Python 2.6, 2.7, 3.3 and 3.4.

Usage[¶](#usage "Permalink to this headline")

---------------------------------------------

The C# language provides a handy way to declare, subscribe to and fire

events. Technically, an event is a “slot” where callback functions (event

handlers) can be attached to - a process referred to as subscribing to an

event. To subscribe to an event:

```

>>> def something\_changed(reason):

...     print "something changed because %s" % reason

...

>>> from events import Events

>>> events = Events()

>>> events.on\_change += something\_changed

```

Multiple callback functions can subscribe to the same event. When the event is

fired, all attached event handlers are invoked in sequence. To fire the event,

perform a call on the slot:

```

>>> events.on\_change('it had to happen')

something changed because it had to happen

```

Usually, instances of `Events` will not hang around loosely like

above, but will typically be embedded in model objects, like here:

```

class MyModel(object):

    def \_\_init\_\_(self):

        self.events = Events()

        ...

```

Similarly, view and controller objects will be the prime event subscribers:

```

class MyModelView(SomeWidget):

    def \_\_init\_\_(self, model):

        ...

        self.model = model

        model.events.on\_change += self.display\_value

        ...

    def display\_value(self):

        ...

```

### Introspection[¶](#introspection "Permalink to this headline")

The `Events` and `\_EventSlot` classes provide

some introspection support. This is usefull for example for automatic event

subscription based on method name patterns.

```

>>> from events import Events

>>> events = Events()

>>> print events

<events.events.Events object at 0x104e5d5f0>

>>> def changed():

...     print "something changed"

...

>>> def another\_one():

...     print "something changed here too"

...

>>> def deleted():

...     print "something got deleted!"

...

>>> events.on\_change += changed

>>> events.on\_change += another\_one

>>> events.on\_delete += deleted

>>> print len(events)

2

>>> for event in events:

...     print event.\_\_name\_\_

...

on\_change

on\_delete

>>> event = events.on\_change

>>> print event

event 'on\_change'

>>> print len(event)

2

>>> for handler in event:

...     print handler.\_\_name\_\_

...

changed

another\_one

>>> print event[0]

<function changed at 0x104e5c230>

>>> print event[0].\_\_name\_\_

changed

>>> print len(events.on\_delete)

1

>>> events.on\_change()

something changed

somethind changed here too

>>> events.on\_delete()

something got deleted!

```

### Event names[¶](#event-names "Permalink to this headline")

Note that by default `Events` does not check if an event that is

being subscribed to can actually be fired, unless the class attribute

`\_\_events\_\_` is defined. This can cause a problem if an event name is

slightly misspelled. If this is an issue, subclass `Events` and

list the possible events, like:

```

class MyEvents(Events):

    \_\_events\_\_ = ('on\_this', 'on\_that', )

events = MyEvents()

# this will raise an EventsException as `on\_change` is unknown to MyEvents:

events.on\_change += changed

```

You can also predefine events for a single `Events` instance by

passing an iterator to the constructor.

```

events = Events(('on\_this', 'on\_that'))

# this will raise an EventsException as `on\_change` is unknown to MyEvents:

events.on\_change += changed

```

It is recommended to use the constructor method for one time use cases. For more

complicated use cases, it is recommended to subclass `Events`

and define `\_\_events\_\_`.

You can also leverage both the constructor method and the `\_\_events\_\_`

attribute to restrict events for specific instances:

```

DatabaseEvents(Events):

    \_\_events\_\_ = ('insert', 'update', 'delete', 'select')

audit\_events = ('select')

AppDatabaseEvents = DatabaseEvents()

# only knows the 'select' event from DatabaseEvents

AuditDatabaseEvents = DatabaseEvents(audit\_events)

```

Installing[¶](#installing "Permalink to this headline")

-------------------------------------------------------

Events is on PyPI so all you need to do is:

```

pip install events

```

Testing[¶](#testing "Permalink to this headline")

-------------------------------------------------

Just run:

```

python setup.py test

```

The package has been tested under Python 2.6, Python 2.7 and Python 3.3.

Source Code[¶](#source-code "Permalink to this headline")

---------------------------------------------------------

Source code is available at [GitHub](https://github.com/pyeve/events).

Attribution[¶](#attribution "Permalink to this headline")

---------------------------------------------------------

Based on the excellent recipe by [Zoran Isailovski](http://code.activestate.com/recipes/410686/), Copyright (c) 2005.

Copyright Notice[¶](#copyright-notice "Permalink to this headline")

-------------------------------------------------------------------

This is an open source project by [Nicola Iarocci](http://nicolaiarocci.com). See the original [LICENSE](https://github.com/pyeve/events/blob/master/LICENSE)

for more informations.

