【问题标题】:Multiple inheritance metaclass conflict多重继承元类冲突
【发布时间】:2015-04-27 12:25:15
【问题描述】:

我需要一个类的双重继承。 我尝试了几种语法,但我不明白元类的概念。

from PyQt5.QtGui import QStandardItem
from configparser import ConfigParser

class FinalClass(ConfigParser, QStandardItem):
    def __init__(self, param):
        ConfigParser.__init__(self)
        QStandardItem.__init__(self)

【问题讨论】:

  • 这里没有元类。您面临什么问题?
  • @MartijnPieters - 他可能指的是此类定义将产生的错误:TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
  • @mata: 啊,所以QStandardItem 大概使用了元类。那么这里真正的问题是为什么 OP 试图在一个类中混合 QStandardItemConfigParser
  • 我需要这个,因为我使用 QStandardItemModel 和 QTableView。每一行都是 FinalClass 的一个实例,每个实例是一个文件。
  • @Mauricio。这不是使用多重继承的好理由。只需将FinalClass 设为QStandardItem 的子类,然后委托给ConfigParser 的内部实例即可。或者,更好的是,忘记使用标准项目,而是使用 Qt 的 ModelL/View Architecture 来创建 custom model

标签: python python-3.x pyqt pyqt5 multiple-inheritance


【解决方案1】:

您的问题是您尝试继承的类具有不同的元类:

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

因此,python 无法决定哪个应该是新创建的类的元类。在这种情况下,它必须是继承自 sip.wrappertype(或旧 PyQt5 版本的 PyQt5.QtCore.pyqtWrapperType)和 ABCMeta 的类。

因此,元类冲突可以通过显式引入这样的元类来解决:

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)

如果您想要更详细的描述,this article 是一个好的开始。

但是我不太相信在这种情况下使用多重继承是一个好主意,特别是与 QObjects 一起使用多重继承可能会很棘手。也许将 ConfigParser 对象存储为实例变量并在需要时使用它会更好。

【讨论】:

  • 非常感谢您的解释和可行的答案。仅用于个人物品。你是对的,我会选择一个 ConfigParser 的实例,否则它会引发其他问题。
  • 感谢您的简洁描述。在我读到这篇文章之前,我很迷茫。
  • 在我的环境中(Python 3.7.2 + Anaconda + PyQt5 5.12 + PyQt5_sip 4.19.14)from PyQt5.QtCore import pyqtWrapperType 不存在。
  • 似乎元类在某个时候从PyQt5.QtCore.pyqtWrapperType 更改为sip.wrappertype。我会更新答案。
【解决方案2】:

您可以使您的base classmetaclass 扩展自Qt 元类系统

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_()

【讨论】:

    猜你喜欢
    • 2011-11-20
    • 2021-10-30
    • 2012-11-14
    • 2012-06-30
    • 1970-01-01
    • 2012-11-26
    • 2011-09-27
    • 2019-02-05
    相关资源
    最近更新 更多