python3 super 不适用于 PyQt 类 [英] python3 super doesn't work with PyQt classes

查看:59
本文介绍了python3 super 不适用于 PyQt 类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

python3中有一个简单的程序:

There is a simple program in python3:

from PyQt4 import QtCore
import PyQt4

class Bar(object):
    def __init__(self):
        print("Bar start")
        super(Bar, self).__init__()
        print("Bar end")

class FakeQObject(object):
    def __init__(self):
        print("FakeQObject start")
        super(FakeQObject, self).__init__()
        print("FakeQObject end")

class Foo(QtCore.QObject, Bar):
#class Foo(FakeQObject, Bar):
    def __init__(self):
        print("Foo start")
        super(Foo, self).__init__()
        print("Foo end")


print(Foo.__mro__)
print(PyQt4.QtCore.PYQT_VERSION_STR)
f = Foo()

a) 当 Foo 类继承自 QtCore.QObject 和 Bar 时,我们得到:

a) When class Foo inherits from QtCore.QObject and Bar we get:

(<class '__main__.Foo'>, <class 'PyQt4.QtCore.QObject'>, <class 'sip.wrapper'>, <class 'sip.simplewrapper'>, <class '__main__.Bar'>, <class 'object'>)
4.9.4
Foo start
Foo end

b) 当 Foo 类继承自 FakeQObject 和 Bar 时,我们得到:

b) When class Foo inherits from FakeQObject and Bar we get:

(<class '__main__.Foo'>, <class '__main__.FakeQObject'>, <class '__main__.Bar'>, <class 'object'>)
4.9.4
Foo start
FakeQObject start
Bar start
Bar end
FakeQObject end
Foo end

问题是:为什么在 a) 的情况下,Bar init 没有被调用?

The question is: why in the a) case, Bar init is not called?

我在这里pyQt4和继承发现了类似的问题,但没有好的答案.

I found similar question here pyQt4 and inheritance but there are no good answers.

提前致谢!

推荐答案

与@nneonneo 一起,我也怀疑 QtCore.QObject 没有使用协作式 super.__init__.如果是这样,你就不会遇到这个问题.

Along with @nneonneo I also suspect that QtCore.QObject doesn't use the cooperative super.__init__. If it did, you wouldn't have this problem.

但是,您应该意识到在某些时候基类之一不能使用协作超级,因为object 没有该方法.考虑:

However, you should be aware that at some point one of the base classes cannot use cooperative super because object won't have the method. Consider:

class Base():
    def __init__(self):
        print("initializing Base")
        super().__init__()
    def helper(self, text):
        print("Base helper")
        text = super().helper(text)
        text = text.title()
        print(text)

class EndOfTheLine():
    def __init__(self):
        print("initializing EOTL")
        super().__init__()
    def helper(self, text):
        print("EOTL helper")
        text = super().helper(text)
        return reversed(text)

class FurtherDown(Base, EndOfTheLine):
    def __init__(self):
        print("initializing FD")
        super().__init__()
    def helper(self, text):
        print(super().helper(text))

test = FurtherDown()
print(test.helper('test 1 2 3... test 1 2 3'))

和输出:

initializing FD
initializing Base
initializing EOTL
Base helper
EOTL helper
Traceback (most recent call last):
  File "test.py", line 28, in <module>
    print(test.helper('test 1 2 3... test 1 2 3'))
  File "test.py", line 25, in helper
    print(super().helper(text))
  File "test.py", line 7, in helper
    text = super().helper(text)
  File "test.py", line 17, in helper
    text = super().helper(text)
AttributeError: 'super' object has no attribute 'helper'

因此,无论哪个类将成为行尾,都不需要调用 super.因为您可能想要覆盖其他 Qt 方法,所以 Qt 类必须是类头中的最后一个.通过不让 __init__ 使用协作超级,即使它可以,Qt 正在避免在其他方法被覆盖时进一步降低错误.

So, whichever class is going to be the End of the Line needs to not call super. Because there are other Qt methods you might want to override, that dictates that the Qt class must be the last one in the class header. By not having __init__ use cooperative super, even though it could, Qt is avoiding bugs further down when some other method is overridden.

这篇关于python3 super 不适用于 PyQt 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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