Event Management System in Python
This challenge focuses on implementing a basic event management system using Python's event handling capabilities. You'll design a system where objects can register for events triggered by other objects, and then react when those events occur. This is a fundamental concept in many software architectures, enabling loose coupling and modularity.
Problem Description
You are tasked with creating a simple event management system. The system should allow objects to:
- Register for Events: An object should be able to subscribe to specific event types (e.g., "button_click", "data_received").
- Trigger Events: Another object should be able to raise (or trigger) an event, specifying the event type and any associated data.
- Handle Events: Registered objects should receive and process events they've subscribed to.
The core of the system will be an EventManager class. This class will maintain a list of subscribers for each event type. When an event is triggered, the EventManager will notify all registered subscribers.
Key Requirements:
- Create an
EventManagerclass with methods for registering subscribers, triggering events, and managing event types. - Subscribers should be functions or methods that can accept event data as an argument.
- The system should support multiple event types.
- The system should handle cases where no subscribers are registered for a particular event.
Expected Behavior:
- When an event is triggered, all registered subscribers for that event type should be called with the event data.
- The order in which subscribers are called is not specified.
- If no subscribers are registered for an event type, the trigger method should not raise an error; it should simply do nothing.
Edge Cases to Consider:
- What happens if an object tries to register for an event type that doesn't exist? (Should it be created?)
- What happens if an object tries to trigger an event type that doesn't exist? (Should it be created?)
- How should the system handle errors within a subscriber function? (Should it prevent other subscribers from being called?) For this challenge, you can assume subscriber functions will not raise exceptions.
Examples
Example 1:
Input:
EventManager instance: em
Subscriber function: def my_handler(data): print(f"Received: {data}")
em.register_subscriber("button_click", my_handler)
em.trigger_event("button_click", "Button 1 clicked")
Output:
Received: Button 1 clicked
Explanation: The subscriber function `my_handler` is registered for the "button_click" event. When the event is triggered with the data "Button 1 clicked", the handler is called, and the message is printed.
Example 2:
Input:
EventManager instance: em
Subscriber function 1: def handler1(data): print(f"Handler 1: {data}")
Subscriber function 2: def handler2(data): print(f"Handler 2: {data}")
em.register_subscriber("data_received", handler1)
em.register_subscriber("data_received", handler2)
em.trigger_event("data_received", "New data available")
Output:
Handler 1: New data available
Handler 2: New data available
Explanation: Two subscriber functions are registered for the "data_received" event. When the event is triggered, both handlers are called in an arbitrary order.
Example 3: (Edge Case - No Subscribers)
Input:
EventManager instance: em
em.trigger_event("unknown_event", "Some data")
Output:
(No output)
Explanation: The event "unknown_event" is triggered, but no subscribers are registered for this event type. Therefore, nothing happens.
Constraints
- The
EventManagerclass should be implemented using Python's built-in data structures (e.g., dictionaries, lists). - Subscriber functions can accept any type of data as an argument.
- The number of event types and subscribers is not limited.
- The system should be reasonably efficient for a small number of events and subscribers (performance optimization is not the primary focus).
Notes
- Consider using a dictionary to store subscribers for each event type. The keys of the dictionary will be event types, and the values will be lists of subscriber functions.
- Think about how to handle the registration and triggering of events in a clean and modular way.
- The focus is on the core event management logic; you don't need to implement a full-fledged user interface or complex data structures.
- This is a good opportunity to practice object-oriented programming and event-driven design principles.