使用PyQt(QMainWindow)使用多重继承进行子类化时python中的MRO [重复]

Posted

技术标签:

【中文标题】使用PyQt(QMainWindow)使用多重继承进行子类化时python中的MRO [重复]【英文标题】:MRO in python when subclassing with multiple inheritance, using PyQt (QMainWindow) [duplicate] 【发布时间】:2018-04-25 08:01:44 【问题描述】:

我最近遇到了TypeError,当我将QMainWindowPyQt5 子类化时我不明白。

创建两个类时:

class Base (QMainWindow):
    def __init__(self):
        super(Base, self).__init__(None)

class Base2 (object):
    def __init__(self, a, b):
        pass

然后创建两者的子类,不带任何初始化参数:

class SubClass( Base, Base2 ):
    def __init__(self):
        Base.__init__(self)
        Base2.__init__(self, 0,0)

创建子类的实例时出现 TypeError:

from PyQt5.QtWidgets import QApplication, QMainWindow    
app = QApplication([])
print( SubClass() )

输出:

Traceback (most recent call last):
    print(SubClass())
    Base.__init__(self)
    super(Base, self).__init__(None)
TypeError: __init__() missing 2 required positional arguments: 'a' and 'b'

但是,当更改继承 class SubClass( Base2, Base ): 的顺序时,代码将运行良好。


我阅读了How does Python's super() work with multiple inheritance? 和Method Resolution Order 的帖子,但没有找到答案。

(另请注意,这有点特定于 PyQt,因为我无法完全基于 object 重现基类的问题)

有人可以对这种行为给出明确的解释吗?

【问题讨论】:

您的实现有很多错误,因此无法做出明确的解释。将super 与显式__init__ 调用混用总是错误的——所有基类都必须使用super。您还需要修复对不匹配签名的处理 - 请参阅 this answer 和 this answer 您链接到的第一个问题。一旦消除了这些问题,基类的顺序就不再重要了。 【参考方案1】:

“将super 与显式__init__ 调用混用总是错误的——所有基类都必须使用super。” - ekhumoro

我不知道这一点 - 谢谢。

此外,基于此,以及 Raymond Hettinger 的 this answer 和 this wordpress article,我认为最好的做法是使用 **kwargs 通过超级调用链传递所有参数并过滤它们的一部分每个初始化的部分:

class Base (QMainWindow):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

class Base2 (object):
    def __init__(self, a, b, **kwargs):
        super().__init__(**kwargs)

class SubClass(Base, Base2): # order can be switched now
    def __init__(self):
        super().__init__(a=0, b=0, parent=None)

这样,MRO 就与本示例无关了。


研究推荐,对于像我这样的其他新手:

雷蒙德·海廷格:

Python’s super() considered super! (wordpress) Super considered super! - PyCon 2015 (youtube)

How does Python's super() work with multiple inheritance (最好在 *** 上)

Super init vs. parent.__init__ Python super method and calling alternatives

【讨论】:

以上是关于使用PyQt(QMainWindow)使用多重继承进行子类化时python中的MRO [重复]的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5学习记录---QMainWindow菜单栏状态栏和工具栏

QWidget 无法在 QMainWindow 实例 PyQt5 上显示

在 Pyqt4 中用不同的 QMainWindow 刷新 QMainWindow

pyqt5,接收 AttributeError:“QMainWindow”对象没有属性“browseSlot”

访问 QMainWindow 类变量 - Pyside/PyQt

QListView 不接受使用 Python PyQt4 在 QMainWindow 中的丢弃