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 '''
Discussion