__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...
  Важно: Использование метаклассов может усложнить код. Их следует использовать только тогда, когда другие подходы, такие как декораторы, миксины или патчи, не подходят. Сложность метаклассов может затруднить понимание и отладку кода, поэтому их следует применять с осторожностью. Четко документируйте цель использования метакласса.
Метаклассы обеспечивают уровень абстракции, позволяющий настраивать процесс создания классов, что дает возможность динамически модифицировать поведение методов в классах, управляемых этим метаклассом.