Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple inheritance metaclass conflict

Tags:

I need a double inheritance for a class. I tried several syntaxes but I don't understand the concept of metaclass.

from PyQt5.QtGui import QStandardItem from configparser import ConfigParser  class FinalClass(ConfigParser, QStandardItem):     def __init__(self, param):         ConfigParser.__init__(self)         QStandardItem.__init__(self) 
like image 344
Mauricio Avatar asked Feb 25 '15 13:02

Mauricio


People also ask

What is metaclass conflict in Python?

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass #of the metaclasses of all its bases. Solution snippet from noconflict import classmaker class C(A,B): __metaclass__=classmaker() print C #<class 'C'>

What is metaclass in OOP?

In object-oriented programming, a metaclass is a class whose instances are classes. Just as an ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain classes and their instances. Not all object-oriented programming languages support metaclasses.

What is a metaclass in Python?

A metaclass in Python is a class of a class that defines how a class behaves. A class is itself an instance of a metaclass. A class in Python defines how the instance of the class will behave. In order to understand metaclasses well, one needs to have prior experience working with Python classes.

Are metaclasses inherited?

Every object and class in Python is either an instance of a class or an instance of a metaclass. Every class inherits from the built-in basic base class object , and every class is an instance of the metaclass type .


2 Answers

The problem in your case is that the classes you try to inherit from have different metaclasses:

>>> type(QStandardItem) <class 'sip.wrappertype'>  >>> type(ConfigParser) <class 'abc.ABCMeta'> 

Therefore python can't decide which should be the metaclass for the newly created class. In this case, it would have to be a class inheriting from both sip.wrappertype (or PyQt5.QtCore.pyqtWrapperType for older PyQt5 versions) and ABCMeta.

Therefore the metaclass conflict could be resolved by explicitly introducing such a class as metaclass like this:

from PyQt5.QtGui import QStandardItem from configparser import ConfigParser  class FinalMeta(type(QStandardItem), type(ConfigParser)):     pass  class FinalClass(ConfigParser, QStandardItem, metaclass=FinalMeta):     def __init__(self, param):         ConfigParser.__init__(self)         QStandardItem.__init__(self) 

If you want a more detailed description, this article is a good start.

However I'm not really convinced that using multiple inheritance for this situaction is such a good idea, specially using multiple inheritance together with QObjects can be tricky. Maybe it would be better to just store the ConfigParser object as an instance variable and use that when needed.

like image 107
mata Avatar answered Oct 30 '22 02:10

mata


You can make your base class's metaclass extends from Qt metaclass system

import abc  from PySide2 import QtWidgets, QtCore   class MixinMeta(type(QtCore.QObject), abc.ABCMeta):     pass   class MyMixin(object, metaclass=MixinMeta):     @abc.abstractmethod     def howToShow(self):         pass      def doShow(self):         self.howToShow()   class MyWidget(QtWidgets.QWidget, MyMixin):     def howToShow(self):         self.show()   app = QtWidgets.QApplication() widget = MyWidget() widget.doShow() app.exec_() 
like image 26
BaiJiFeiLong Avatar answered Oct 30 '22 01:10

BaiJiFeiLong