Вы можете изменить метакласс после создания класса так же, как вы можете изменить класс объекта, однако у вас будет много проблем. Для начала, начальный метакласс должен отличаться от type
, __init__
и __new__
нового метакласса не будут вызываться (хотя вы можете вручную вызвать __init__
или метод, который выполняет __init__
' с работы).
Возможно, наименее хлопотный способ изменить метакласс - это воссоздать класс заново с нуля:
B = MetaClass(B.__name__, B.__bases__, B.__dict__)
Но если вы настаиваете на динамическом изменении метакласса, вам сначала нужно определить B с помощью временного пользовательского метакласса:
class _TempMetaclass(type):
pass
class B:
__metaclass__ = _TempMetaclass # or: type('temp', (type, ), {})
Тогда вы можете определить метакласс следующим образом:
class MetaClass(type):
def __init__(cls, *a, **kw):
super(MetaClass, cls).__init__(*a, **kw)
cls._actual_init(*a, **kw)
def _actual_init(cls, *a, **kw):
# actual initialization goes here
А затем сделайте что-то вроде:
B.__class__ = MetaClass
MetaClass._actual_init(B, B.__name__, B.__bases__, B.__dict__)
Вам также необходимо убедиться, что вся инициализация класса выполнена _actual_init
. Вы также можете добавить classmethod
к метаклассу, который изменит метакласс для вас.
Оба решения имеют небольшой недостаток, заключающийся в том, что базы B будут ограничены - они должны быть совместимы как с оригинальным, так и с новым метаклассом, но я думаю, что это не проблема в вашем случае.