Метаклассы
Класс класса. Управляем созданием классов.
Метакласс — это класс класса
Когда ты пишешь class A: ..., Python вызывает метакласс (по умолчанию type), который и создаёт объект-класс. Подменив метакласс, ты вмешиваешься в момент создания класса: можешь добавить атрибуты, провалидировать структуру, зарегистрировать класс в реестре, переписать методы — всё ещё до того, как кто-то создаст первый экземпляр.
Как это читается
class Meta(type):
def __new__(mcs, name, bases, ns):
ns["created_by"] = "Meta"
return super().__new__(mcs, name, bases, ns)
class A(metaclass=Meta):
pass
print(A.created_by) # Meta
__new__ получает имя будущего класса, его базы и ns — словарь тела класса (методы, атрибуты). Возвращает готовый класс через super().__new__.
Пример: автоматическая регистрация
REGISTRY = {}
class Plugin(type):
def __new__(mcs, name, bases, ns):
cls = super().__new__(mcs, name, bases, ns)
if bases: # пропускаем базовый
REGISTRY[name] = cls
return cls
class Base(metaclass=Plugin): pass
class Json(Base): pass
class Yaml(Base): pass
print(list(REGISTRY)) # ['Json', 'Yaml']
Когда использовать / подводные камни
👍 ORM (SQLAlchemy, Django models), фреймворки плагинов, DSL с валидацией структуры классов на момент объявления.
👎 В 95% случаев достаточно декоратора класса или __init_subclass__ — они проще, наследуются предсказуемо и не порождают конфликтов метаклассов при множественном наследовании. Метакласс — последний инструмент, к которому стоит тянуться.