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

MRO in python when subclassing with multiple inheritance, using PyQt (QMainWindow)

我最近经历了一个 TypeError,当我用 PyQt5.

子类化 QMainWindow 时我不明白

创建两个时类:

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)

我在创建子类的实例时遇到类型错误:

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? and Method Resolution Order 中的 post,但没有找到这方面的答案。

(另请注意,这在某种程度上是 PyQt 特有的,因为我无法完全基于 object 重现 Base-类 的问题)

谁能对这种行为给出一个明确的解释?

"It is always wrong to mix super with explict __init__ calls - all the base-classes must use super." - ekhumoro

我不知道这个 - 谢谢。

此外,基于此以及 Raymond Hettinger 的 this answer and 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 就与这个例子无关了。


研究推荐,给和我一样的新手: