Metaclasses
Python · Advanced · Run with python3
Explanation
A metaclass is the class of a class — it controls how classes are created. `type` is the default metaclass of all Python classes. Custom metaclasses override `__new__` and `__init__` to intercept class creation: adding methods, validating class definitions, registering classes, or enforcing interfaces. The `__init_subclass__` hook (Python 3.6+) is a simpler alternative for many metaclass use cases. `abc.ABCMeta` is the most widely used metaclass — it powers `@abstractmethod`.
Real-World Scenario
Django's ORM uses a metaclass to transform class-level field declarations (`name = CharField(max_length=100)`) into a table schema and query interface. The metaclass intercepts class creation and replaces `CharField` instances with descriptors wired to the database. ```python class SingletonMeta(type): """Metaclass that ensures only one instance per class.""" _instances: dict = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls] class Config(metaclass=SingletonMeta): def __init__(self): self.debug = False self.version = "1.0" a = Config() b = Config() print(a is b) # True — same instance a.debug = True print(b.debug) # True — same object # __init_subclass__ — simpler registration pattern class Plugin: _registry: dict[str, type] = {} def __init_subclass__(cls, name: str = "", **kwargs): super().__init_subclass__(**kwargs) if name: Plugin._registry[name] = cls class AuthPlugin(Plugin, name="auth"): def run(self): return "auth" print(Plugin._registry) # {'auth': <class 'AuthPlugin'>} ```
Quick Snippet
class SingletonMeta(type):
"""Metaclass that ensures only one instance per class."""
_instances: dict = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Config(metaclass=SingletonMeta):
def __init__(self):
self.debug = False
self.version = "1.0"
a = Config()
b = Config()
print(a is b) # True — same instance
a.debug = True
print(b.debug) # True — same object
# __init_subclass__ — simpler registration pattern
class Plugin:
_registry: dict[str, type] = {}
def __init_subclass__(cls, name: str = "", **kwargs):
super().__init_subclass__(**kwargs)
if name:
Plugin._registry[name] = cls
class AuthPlugin(Plugin, name="auth"):
def run(self): return "auth"
print(Plugin._registry) # {'auth': <class 'AuthPlugin'>}Full Example
# Compile: python3 metaclasses.py
# Output:
# True
# True
# {'auth': <class '__main__.AuthPlugin'>}
class SingletonMeta(type):
_instances: dict = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Config(metaclass=SingletonMeta):
def __init__(self):
self.debug = False
a = Config()
b = Config()
print(a is b) # True
a.debug = True
print(b.debug) # True — same object
class Plugin:
_registry: dict = {}
def __init_subclass__(cls, name: str = "", **kwargs):
super().__init_subclass__(**kwargs)
if name:
Plugin._registry[name] = cls
class AuthPlugin(Plugin, name="auth"):
def run(self): return "auth"
print(Plugin._registry)
python3 metaclasses.py