__init_subclass__ Hook (PEP 487) as Metaclass Alternative
1Concept
PEP 487 introduced `__init_subclass__()` in Python 3.6. It allows base classes to intercept subclass creation, configure plugin registries, and validate subclass parameters without the complexity of metaclasses.
2Architecture Diagram
Subclass Creation ---> ParentClass.__init_subclass__() automatically notified!
3Code Example
Python 3.12
class PluginBase:
registry = {}
def __init_subclass__(cls, plugin_name: str, **kwargs):
super().__init_subclass__(**kwargs)
cls.registry[plugin_name] = cls
print(f"Registered plugin '{plugin_name}' -> {cls.__name__}")
class S3StoragePlugin(PluginBase, plugin_name="s3"):
pass
class GcsStoragePlugin(PluginBase, plugin_name="gcs"):
pass
print(f"Active Plugin Registry: {PluginBase.registry}")4Expected Output
Registered plugin 's3' -> S3StoragePlugin
Registered plugin 'gcs' -> GcsStoragePlugin
Active Plugin Registry: {'s3': <class '__main__.S3StoragePlugin'>, 'gcs': <class '__main__.GcsStoragePlugin'>}5Key Takeaways
- ✓`__init_subclass__` accepts arbitrary keyword arguments passed in the subclass definition line.
- ✓Drastically simpler and more maintainable than full metaclass hierarchies.
- ✓Ideal for plugin registration, schema validation, and API serialization mapping.