Метаклассы — это "классы классов" в Python. Они определяют поведение и структуру самих классов. Другими словами, метакласс управляет созданием и изменением классов, так же как класс управляет созданием и изменением объектов.
В Python всё является объектом, включая классы. Классы создаются с помощью метаклассов. По умолчанию метаклассом для всех классов является type
. Однако вы можете создать собственный метакласс, чтобы изменить стандартное поведение при создании классов.
class Meta(type):
def __new__(cls, name, bases, dct):
# Добавляем новый атрибут к классу
dct['created_by'] = 'Meta'
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=Meta):
pass
print(MyClass.created_by) # Вывод: Meta
Здесь:
Meta
— это метакласс, который наследует от type
.__new__
метакласса вызывается при создании класса. Он может изменять атрибуты класса перед его созданием.MyClass
использует Meta
как метакласс, и в результате получает новый атрибут created_by
.__new__
: Создает класс.__init__
: Инициализирует класс после его создания.__prepare__
: Возвращает пространство имен для класса (например, упорядоченный словарь).class OrderedMeta(type):
@classmethod
def __prepare__(cls, name, bases):
from collections import OrderedDict
return OrderedDict()
def __new__(cls, name, bases, dct):
dct['creation_order'] = list(dct.keys())
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=OrderedMeta):
attr1 = 1
attr2 = 2
print(MyClass.creation_order) # Вывод: ['__module__', '__qualname__', 'attr1', 'attr2']
Здесь:
__prepare__
возвращает упорядоченный словарь, чтобы сохранить порядок объявления атрибутов.__new__
добавляет атрибут creation_order
, который содержит порядок объявления атрибутов класса.class PluginMeta(type):
registry = []
def __new__(cls, name, bases, dct):
new_class = super().__new__(cls, name, bases, dct)
if name != 'Plugin':
cls.registry.append(new_class)
return new_class
class Plugin(metaclass=PluginMeta):
pass
class PluginA(Plugin):
pass
class PluginB(Plugin):
pass
print(PluginMeta.registry) # Вывод: [<class '__main__.PluginA'>, <class '__main__.PluginB'>]
Здесь:
PluginMeta
автоматически регистрирует все подклассы Plugin
в списке registry
.Метаклассы — это мощный инструмент для управления созданием и поведением классов в Python. Они полезны для:
Однако их следует использовать с осторожностью, так как они могут усложнить код. В большинстве случаев вместо метаклассов можно использовать более простые механизмы, такие как декораторы.