Skip to content

Instantly share code, notes, and snippets.

@janaSunrise
Created October 21, 2022 05:41
Show Gist options
  • Save janaSunrise/68a3c00bf734282d1213430915696f7f to your computer and use it in GitHub Desktop.
Save janaSunrise/68a3c00bf734282d1213430915696f7f to your computer and use it in GitHub Desktop.
Event emitter in python
from collections import defaultdict
from typing import Callable, Optional
HandlerFunction = Callable[..., None]
class EventHandler:
def __init__(self):
self.handlers = defaultdict(list)
def on(self, event: str) -> Callable[[HandlerFunction], HandlerFunction]:
def register_handler(handler: HandlerFunction) -> HandlerFunction:
self.handlers[event].append(handler)
return handler
return register_handler
def once(self, event: str) -> Callable[[HandlerFunction], HandlerFunction]:
def register_handler(handler: HandlerFunction) -> HandlerFunction:
def wrapper(*args, **kwargs) -> None:
handler(*args, **kwargs)
self.off(event, wrapper)
self.handlers[event].append(wrapper)
return handler
return register_handler
def off(self, event: str, handler: Optional[HandlerFunction] = None) -> None:
if handler is None:
self.handlers[event] = []
else:
self.handlers[event].remove(handler)
def emit(self, event: str, *args, **kwargs) -> None:
for handler in self.handlers[event]:
handler(*args, **kwargs)
if __name__ == "__main__":
event_handler = EventHandler()
@event_handler.on("test")
def test_handler_add(a: int, b: int) -> None:
print(a + b)
@event_handler.once("test")
def test_handler_sub(a: int, b: int) -> None:
print(a - b)
# Both should run
event_handler.emit("test", 1, 2)
# After running the `once`
event_handler.emit("test", 1, 2)
# None should run
event_handler.off("test", test_handler_add)
event_handler.emit("test", 1, 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment