我最近遇到了TypeError
,当我使用PyQt5
将QMainWindow
子类化时,我不明白。
创建两个类时:
class Base (QMainWindow):
def __init__(self):
super(Base, self).__init__(None)
class Base2 (object):
def __init__(self, a, b):
pass
然后创建两者的子类,没有任何init参数:
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
重现基类的问题)
有人可以对这种行为做出明确的解释吗?
答案 0 :(得分:1)
“将
super
与explict__init__
调用混合在一起总是错误的 - 所有基类必须使用super。” - ekhumoro
我没有意识到这一点 - 谢谢。
此外,基于此,以及Raymond Hettinger的this answer和this wordpress article,我最好使用**kwargs
通过超链接传递所有参数-calls并逐个过滤每个init:
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与此示例无关。
研究建议,对于像我这样的其他新手:
Raymond Hettinger:
How does Python's super() work with multiple inheritance (最好使用stackoverflow)