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