background
TypeError: metaclass conflict: TypeError: metaclass conflict: The metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases. That is, the abstract method YYy cannot be found in the parent class ClassA, and the method yyy is defined in the metaclass of the parent class ClassB, but the method is not defined in the metaclass of ClassA.
class Meta1(type) :
def __new__(mcs, *args, **kwargs) :
return super(Meta1, mcs).__new__(mcs, *args, **kwargs)
class Meta2(type) :
def __new__(mcs, *args, **kwargs) :
return super(Meta2, mcs).__new__(mcs, *args, **kwargs)
class Body(metaclass=Meta1) :
pass
class Head(metaclass=Meta2) :
pass
class Human(Body, Head) :
pass
Copy the code
Solution:
- All metaclasses involved in multiple parent classes have inheritance relationships
- Build a metaclass of your own that inherits all the metaclasses involved in the parent class
implementation
All metaclasses involved in multiple parent classes have inheritance relationships
class Meta1(type) :
def __new__(mcs, *args, **kwargs) :
return super(Meta1, mcs).__new__(mcs, *args, **kwargs)
# Change part: Meta2 inherited from Meta1
class Meta2(Meta1) :
def __new__(mcs, *args, **kwargs) :
return super(Meta2, mcs).__new__(mcs, *args, **kwargs)
class Body(metaclass=Meta1) :
pass
class Head(metaclass=Meta2) :
pass
class Human(Body, Head) :
pass
Copy the code
Meta2 is a subclass of Meta1. Creating a Human class will execute Meta2’s new method.
Build a metaclass of your own that inherits all the metaclasses involved in the parent class
class Meta1(type) :
def __new__(mcs, *args, **kwargs) :
return super(Meta1, mcs).__new__(mcs, *args, **kwargs)
class Meta2(type) :
def __new__(mcs, *args, **kwargs) :
return super(Meta2, mcs).__new__(mcs, *args, **kwargs)
class Body(metaclass=Meta1) :
pass
class Head(metaclass=Meta2) :
pass
# Change part: The new metaclass inherits all involved metaclasses
class CombineMeta(Meta1, Meta2) :
pass
Set the metaclass
class Human(Body, Head, metaclass=CombineMeta) :
pass
Copy the code
Perhaps Meta1 and Meta2 metaclasses cannot be changed for various reasons. In this case, you can customize metaclasses to inherit these independent metaclasses to avoid metaclass conflicts.
Refer to the link
Multiple inheritance of the Python3 metaclass