Events (pyeve)
The 'events' library for Python, currently at version 0.5, aims to bring the elegance of C# EventHandler to Python. It provides a simple, lightweight mechanism for event subscription and firing, encapsulating the core functionality for attaching and invoking callback functions (event handlers) in sequence, thus facilitating event-driven programming patterns in a straightforward manner. The library is considered mature and stable, with its last release in July 2023, and sees infrequent updates.
Warnings
- gotcha The `Events()` instance holds strong references to subscribed callback functions. If an event handler is a method of an object, and the `Events` instance outlives that object, it can prevent the object from being garbage collected, leading to memory leaks. Always explicitly unsubscribe handlers using `-=` when they are no longer needed, especially for object methods.
- gotcha By default, `Events` instances do not predefine event names. This means you can subscribe to and fire any arbitrary event name (e.g., `events.on_typo`). This flexibility can lead to subtle bugs due to typos in event names that might go unnoticed. For stricter validation, you can predefine events.
- gotcha The package name 'events' is highly generic. There are several other Python libraries and standard library modules (e.g., `eventsourcing`, `pyventus`, `python-dispatch`, `threading.Event`) that deal with event-related patterns. Ensure you are installing and using `pyeve/events` if this is your intended library.
Install
-
pip install events
Imports
- Events
from events import Events
Quickstart
from events import Events
def my_event_handler(reason, data=None):
print(f"Event fired: {reason}")
if data:
print(f" Data: {data}")
# Create an Events instance
app_events = Events()
# Subscribe a handler to an event named 'on_change'
app_events.on_change += my_event_handler
# Fire the 'on_change' event
print("Firing event: 'initial change'")
app_events.on_change("initial change", data={"user": "admin"})
# Subscribe another handler to the same event
def another_handler(reason):
print(f"Another handler received: {reason}")
app_events.on_change += another_handler
# Fire the event again
print("\nFiring event again: 'second change'")
app_events.on_change("second change")
# Unsubscribe a handler
app_events.on_change -= my_event_handler
# Fire the event one last time (only 'another_handler' will be invoked)
print("\nFiring event after unsubscription: 'final change'")
app_events.on_change("final change")