使用PyQt(QMainWindow)在具有多重继承的子类化时在python中进行MRO [英] MRO in python when subclassing with multiple inheritance, using PyQt (QMainWindow)

查看:166
本文介绍了使用PyQt(QMainWindow)在具有多重继承的子类化时在python中进行MRO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了TypeError,当我将

I recently experienced a TypeError, that I didn't understood when I was subclassing a QMainWindow with PyQt5.

创建两个类时:

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

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

,然后创建两者的子类,而没有任何初始化参数:

and then creating a Subclass of both, without any init arguments:

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

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

I get a TypeError when creating an instance of the subclass:

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 ):的顺序时,代码将正常运行.

However, when changing the Order for the inheritance class SubClass( Base2, Base ): the code will run fine.

我在阅读了Python的super()如何与多重继承一起工作?

I read the post in How does Python's super() work with multiple inheritance? and Method Resolution Order but didn't found an answer on this.

(还要注意,这在某种程度上是PyQt特定的,因为我无法完全基于object重现基本类的问题)

(Also note that this is somewhat PyQt-specific, because I couldn't reproduce the problem with Base-classes entirely based on object)

有人可以对此行为做出清楚的解释吗?

Could someone give a clear explanation for this behaiviour?

推荐答案

super与明确的__init__调用混合在一起总是错误的-所有基类都必须使用super. - ekhumoro

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

我不知道这一点-谢谢.

I wasn't aware of this - thanks.

此外,基于此以及此答案

Furthermore, based on that, as well as on this answer and this wordpress article by Raymond Hettinger, it seems best practise to me to use **kwargs to pass all arguments trough the chain of super-calls and filter them part by part for each 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就变得无关紧要了.

this way the MRO gets irrelevant for this example.

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

Research recommendation, for other newbies like me:

  • Raymond Hettinger:

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

Python的super()如何实现多重继承 (在stackoverflow上最好)

这篇关于使用PyQt(QMainWindow)在具有多重继承的子类化时在python中进行MRO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆