简短版(tl;dr)
我正在学习 PySide,大部分在线教程都使用super
来初始化 UI 元素。这个重要吗(例如,更可扩展),还是只是个人喜好?
澄清:如我在详细版中所述,这不是另一个普通的线程询问何时使用 super
(这已经被讨论过了)。相反,考虑到使用 super
而不是 <class>.__init__
的 PySide 教程数量,我试图弄清楚在 PySide 应用程序中使用 super
是否标准?如果是这样的话,是因为需要调用 super
的情况(涉及解决继承)特别多,而这些情况在使用 PySide/PyQt 时经常出现的缘故?还是这只是个人喜好。
详细版
我刚接触 Python,并且正在使用 Zets 教程(http://zetcode.com/gui/pysidetutorial/firstprograms/)学习 PySide。教程的第二个例子包括:
from PySide import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300,300,250,150)
self.setWindowTitle("PySide 101: Window the First!")
self.show()
app=QtGui.QApplication(sys.argv)
ex=Example()
sys.exit(app.exec_())
这段代码本来就能正常工作,但我从未使用过super
。因此,我重写了上面的代码,成功地用更标准的显式调用父类替换了super
:
QtGui.QWidget.__init__(self)
我搜索了PySide教程(例如,http://qt-project.org/wiki/PySide-Newbie-Tutorials),发现它们全部都包含对super
的调用。我的问题是:在PySide脚本中是否应该使用super
?
看起来super
在具有继承菱形的情况下最为有用,因为它倾向于以合理的方式解析多重继承的实例。在PySide中经常使用super
是因为这种菱形的情况很普遍,我将在更加复杂的实际例子中面临这种情况吗?[编辑:不需要,见下文]
为什么我要问这个问题?直接使用super
不就好了吗?
我问这个问题是因为我学习Python的书籍(《Learning Python》by Lutz)在“super
”这个主题上花费了超过20页,并明确告诫不要使用它。他建议新的Python用户在尝试使用super
之前先走传统、明确的路线(例如,参见《Python基础教程》第5版的832页和1041-1064页)。他基本上将其描绘成一种不Pythonic、奥妙难解、很少实际需要的新风格,在刚开始时应该非常谨慎地对待它,并认为它被经验丰富的用户过度使用。
此外,查看两个基于PySide/PyQt的主要项目(Spyder和pyqtgraph)的源代码,均未使用super
。其中一个项目(Spyder)明确告诉贡献者出于兼容性原因避免使用它(http://code.google.com/p/spyderlib/wiki/NoteForContributors)。
请注意,我在下面链接了一个密切相关的帖子,但那里的答案更普遍地讨论了何时需要使用super
(当你有多重继承时)。我的问题是:在长期使用中,PySide脚本是否证明了或需要使用super
,或者显式命名父类更符合Python的规范性和兼容性原因?还是只是个人口味问题?
如果它受到贬低(如我的初学者书籍所示),那么为什么在面向初学者的PySide教程中它如此普遍?如果有区别的话,似乎撰写这些教程的人都是经验丰富的Java程序员或为这样的程序员提供服务。但我不是。
相关主题
http://www.riverbankcomputing.com/pipermail/pyqt/2008-January/018320.html
<class>.__init(self,...)
,但最近我在原本子类化(假设)QWidget
并覆盖了一堆方法时遇到了问题,在某些时候调用了父类方法。后来我将我的类更改为子类化QMainWindow
,但忘记更改所有的QWidget.<method>
调用。使用super()
会更容易些。 - three_pineapplesparent_cls.__init__
,还想在扩展功能时调用其他方法(例如,你的getText()
实现可能想要调用parent_cls.getText()
)。使用super
可以避免手动更新每个使用它的地方的parent_cls
。 - three_pineapplessuper().__init__()
,甚至比BaseClass.__init__(self)
还要短。 - Kos