Pure python and very simple event management library

In event driven programming events are crucial. My requirements was Micropython platform on ESP32 micro-controller, so i could not use any other events library out-there. I've stumbled one very basic, very simple library and gave it a try… and it worked out-of-the-box for my case. When testing various event management libs out there I've stumbled on something similar, but it did not worked within classes. Python is nothing but classes everywhere :)

I was testing and extended this very simple python script, that perfectly works as main element in event driven development.

Strengths of library:

  • Observer can be declared before event type is created
  • Events can be fired even if there is no observers.
  • Works as pure python script
  • Works on micropython platform
  • Event name can be any string

I'm using this solution for event for timer, that fires each second and observe “ticker” where i need to update clock. I use clock in multiple places in my micropython script and i can get away with just one hardware timer used.

Honorable mentions goes to Pithikos from StackOverflow this answer

I have extended this library with possibility to forget event.

EventObserver.py
class Observer():
    _observers = []
 
    def __init__(self):
        self._observers.append(self)
        self._observed_events = []
 
    def observe(self, event_name, callback_fn):
        self._observed_events.append({'event_name': event_name, 'callback_fn': callback_fn})
 
    def forget(self, event_name):
        for dict_item in self._observed_events:
            for key, val in dict_item.items():
                if val == event_name:
                    self._observed_events.remove(dict_item)
 
 
class Event():
    def __init__(self, event_name, *callback_args):
        for observer in Observer._observers:
            for observable in observer._observed_events:
                if observable['event_name'] == event_name:
                    observable['callback_fn'](*callback_args)

Here is example of how to use this library

example.py
import EventObserver
 
# class object MUST inherit Observer object if you use it within class
class Room(Observer):
    def __init__(self):
        print("Room is ready.")
        Observer.__init__(self)  # DON'T FORGET THIS
        # observer can be declared already in class init method with following line
        # this.observe('someone sneezed', this.someone_sneezed)
 
    def someone_arrived(self, who):
        print("{} has arrived!".format(who))
 
    def someone_sneezed(self, who):
        print("{} has just sneezed!".format(who))
 
 
# Observe for specific event
room = Room()
room.observe('arrived', room.someone_arrived)
room.observe('sneezed', room.someone_arrived)
 
# Fire some events
Event('left', 'John')       # no events are attached to event "someone left" 
Event('arrived', 'Lenard')  # will output "Lenard has arrived!"
Event('sneezed', 'Jenny')   # will output "Jenny has just sneezed!"
 
# Remove known event
room.forget('arrived')
 
# no events based on 'someone arrived' will be fired
'''
Enter your comment. Wiki syntax is allowed:
If you can't read the letters on the image, download this .wav file to get them read to you.
 
  • blog/201107_pure_python_and_very_simple_event_management_library.txt
  • Last modified: 2021/04/04 00:21
  • by Ignas