Skip to content

Instantly share code, notes, and snippets.

@wulymammoth
Last active February 20, 2023 17:24
Show Gist options
  • Save wulymammoth/84ed1db29138539dbd3ad6e65260c4be to your computer and use it in GitHub Desktop.
Save wulymammoth/84ed1db29138539dbd3ad6e65260c4be to your computer and use it in GitHub Desktop.
Python 3: registry with auto-subclass registration
from abc import abstractmethod
from collections import defaultdict
from dataclasses import dataclass
from typing import Any
from typing import Union
@dataclass(frozen=True)
class Event:
name: str
payload: Any
class EventHandler:
# This is a class attr
_event_registry = defaultdict(list)
def __init__(self, event):
self._handle(event) # required to be implemented by subclasses
@staticmethod
@abstractmethod
def _handle(event) -> Any:
raise NotImplementedError
def __init_subclass__(cls):
"""Automatic subclass registration.
This method is called whenever the containing class is subclassed.
"""
if not hasattr(cls, "event_type"):
raise TypeError("Subclasses must define an event_type")
cls._event_registry[cls.event_type].append(cls)
@classmethod
def registered_handlers(cls, event: Union[Event, str]):
if isinstance(event, Event):
event = event.name
return cls._event_registry[event]
class FlightHandlerOne(EventHandler):
event_type = "flight"
@staticmethod
def _handle(event: Event):
print(event.payload)
class FlightHandlerTwo(EventHandler):
event_type = "flight"
@staticmethod
def _handle(event: Event):
for ch in list(event.payload):
print(ch)
for handler in EventHandler.registered_handlers("flight"):
some_event = Event("flight", "some payload")
handler(some_event)
'''
$ python subclass_registry.py
some payload
s
o
m
e
p
a
y
l
o
a
d
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment