В Python классы — тоже объекты, и они создаются другим объектом — метаклассом (по умолчанию это type).
Когда интерпретатор видит class MyClass(...): ..., он в итоге вызывает метакласс примерно так:
MyClass = MetaClass(name, bases, attrs_dict)где: имя класса, базовые классы и словарь атрибутов передаются в метакласс. Обычный путь: используется встроенный метакласс type, он просто создаёт класс из этих данных. Если ты задаёшь metaclass=MyMeta, то вместо type вызывается твой метакласс, и у тебя есть точка, где можно перехватить создание класса, что‑то поменять и вернуть модифицированный класс.
class MyMeta(type):
def __new__(mcls, name, bases, attrs):
print("Создаём класс:", name)
# например, добавим атрибут
attrs["from_meta"] = True
return super().__new__(mcls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
print(MyClass.from_meta) # TrueЗдесь MyMeta.__new__ вызывается в момент определения MyClass, и именно он создаёт объект класса, добавляя ему атрибуты.
Когда метаклассы применяют?
Метаклассы — тяжёлая артиллерия; их используют редко и обычно на уровне фреймворков или больших библиотек, когда нужно повлиять на множество классов сразу:
ORM и модели - Django ORM, SQLAlchemy и другие используют метаклассы для обработки определения моделей. При написании класса модели метакласс собирает поля, строит метаданные и генерирует нужные методы/SQL‑структуры.
Автоматическая регистрация классов - плагины, команды CLI, обработчики событий: метакласс может автоматически регистрировать каждый новый подкласс в реестре, чтобы не писать ручной boilerplate.
Валидация и навязывание интерфейса - метакласс может при создании класса проверять, что он определил нужные методы/атрибуты, не нарушил контракт и т.п.
Создание DSL и магии уровня фреймворка - когда хочется, чтобы объявление классов выглядело как мини‑язык (описание схемы БД, конфигов, правил доступа и т.д.), метакласс может превратить объявленный класс в нужную структуру данных или обёртку.
Для ежедневного прикладного кода обычно хватает декораторов, миксинов, фабрик и классов, а к метаклассам имеет смысл прибегать, только если ты реально проектируешь фреймворк или инфраструктурный слой и тебе нужно «одним движением» менять или проверять все классы определённого семейства в момент их объявления.
Формулировка для собеседования
В Python классы сами по себе объекты, и их создаёт метакласс. По умолчанию это type, который получает имя, базовые классы и словарь атрибутов и на их основе конструирует объект класса. Если задать свой metaclass=..., можно перехватить момент создания класса: перед его созданием модифицировать атрибуты, навесить регистрацию, проверки, сгенерировать методы и вернуть уже обработанный класс. Метаклассы используются редко, в основном в библиотеках и фреймворках: ORM, плагинные системы, DSL и места, где нужно автоматом модифицировать или регистрировать семейство классов. В прикладном коде чаще достаточно декораторов и обычных классов, потому что метаклассы усложняют понимание и поддержку.