You can change the metaclass after class creation the same way that you can change the class of an object, however you'd have a lot of issues. For starters, the initial metaclass needs to be different from type
, the __init__
and __new__
of the new metaclass won't be called (though you can manually call __init__
or a method that performs __init__
's job).
Possibly the least troublesome way to change the metaclass is to recreate the class again from scratch:
B = MetaClass(B.__name__, B.__bases__, B.__dict__)
But if you insist on changing the metaclass dynamically, you first need to define B with a temporary custom metaclass:
class _TempMetaclass(type):
pass
class B:
__metaclass__ = _TempMetaclass # or: type('temp', (type, ), {})
Then you can define the metaclass like that:
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
And then do something like:
B.__class__ = MetaClass
MetaClass._actual_init(B, B.__name__, B.__bases__, B.__dict__)
You also need to make sure that all the initialization of the class is done _actual_init
. You can also add a classmethod
to the metaclass that changes the metaclass for you.
Both solutions have the slight shortcoming that B's bases would be limited - they need to be compatible with both the original and the new metaclass, but I guess that's not an issue in your case.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…