Как создаётся класс. Инструкция class выполняет тело класса, собирает пространство имён и вызывает метакласс: Meta(name, bases, namespace). Результат — объект класса.
class Registry(type):
classes = {}
def __new__(mcs, name, bases, ns):
cls = super().__new__(mcs, name, bases, ns)
mcs.classes[name] = cls
return cls
class Plugin(metaclass=Registry): ...
Что умеет метакласс: менять пространство имён до создания класса (__prepare__), проверять или переписывать атрибуты, управлять isinstance (__instancecheck__ в ABCMeta), перехватывать вызов класса (__call__ — например, синглтон).
Лёгкие альтернативы:
class Plugin:
registry = {}
def __init_subclass__(cls, **kw):
super().__init_subclass__(**kw)
Plugin.registry[cls.__name__] = cls
Декоратор класса — для изменения одного класса; __init_subclass__ (Python 3.6) — для реакции на наследников; дескрипторы с __set_name__ — для полей.
Где метаклассы оправданы: фреймворки с декларативным синтаксисом (ORM-модели, Enum), где нужен контроль над созданием класса целиком.