问题描述
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 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!