__new__
или __init__
. Внутри этих методов можно проверять атрибуты класса (например, наличие определенной аннотации или переменной) и, в зависимости от них, изменять атрибут __dict__
класса, добавляя или изменяя методы. Например, можно добавить логирование в методы, если класс имеет определенный флаг.
Метаклассы предоставляют мощный механизм для динамического изменения поведения методов в Python. Это можно сделать несколькими способами:
Пример:
class Meta(type):
def __new__(mcs, name, bases, attrs):
# Добавляем метод 'say_hello', если его нет
if 'say_hello' not in attrs:
attrs['say_hello'] = lambda self: print("Hello from dynamically added method!")
# Декорируем существующий метод 'greet', если он есть
if 'greet' in attrs and callable(attrs['greet']):
original_greet = attrs['greet']
def decorated_greet(self, name):
print("Before greeting...")
original_greet(self, name)
print("After greeting...")
attrs['greet'] = decorated_greet
return super().__new__(mcs, name, bases, attrs)
class MyClass(metaclass=Meta):
def greet(self, name):
print(f"Hello, {name}!")
obj = MyClass()
obj.say_hello() # Выведет: Hello from dynamically added method!
obj.greet("Alice") # Выведет: Before greeting..., Hello, Alice!, After greeting...
Важно: Использование метаклассов может усложнить код. Их следует использовать только тогда, когда другие подходы, такие как декораторы, миксины или патчи, не подходят. Сложность метаклассов может затруднить понимание и отладку кода, поэтому их следует применять с осторожностью. Четко документируйте цель использования метакласса.
Метаклассы обеспечивают уровень абстракции, позволяющий настраивать процесс создания классов, что дает возможность динамически модифицировать поведение методов в классах, управляемых этим метаклассом.