Registry¶
The registry module, located at pyutils.registry, provides a flexible system for registering and managing classes, functions, and other entities within an application. This enables the creation of modular and easily extendable applications by allowing components to be dynamically registered and retrieved as needed.
Implementation¶
The registry system is implemented through two primary functions:
- register(obj=None, *, name=None, discoverable=True)¶
Decorator to mark a class or function as discoverable.
- discover(path, parent_class=None, return_locations=False)¶
Discover all objects marked with _discoverable = True inside a file or directory. Optionally filter by subclass.
- Parameters:
path (str) – Path to a Python file or directory.
parent_class (type or str, optional) – If provided, only return classes that are subclasses of this type. Can be a class object or a fully qualified class name as a string (e.g. “mypkg.BasePlugin”).
- Returns:
dict[str, Callable | Type] – Discovered objects.
In this case the register function is used to register classes or functions with a unique name, while the discover function allows for retrieving all registered entities within a specified module or package.
Examples¶
Here are some examples of how to use the registry system:
from pyutils.registry import register, discover
# Define a sample class
@register('my_class')
class MyClass:
def greet(self):
return "Hello, World!"
@register('another_class')
class AnotherClass:
def __init__(self, myName: str):
print("Hello from " + myName + "!")
def farewell(self, name: str):
return f"Goodbye, {name}!"
# Discover and instantiate the class my_class
cls = discover(__file__)['my_class']
instance = cls()
print(instance.greet()) # Output: Hello, World!
# Discover and instantiate the class another_class
another_cls = discover(__file__)['another_class']
another_instance = another_cls("Mario") # Output: Hello from Mario!
print(another_instance.farewell("Alice")) # Output: Goodbye, Alice!