短版本(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)
但是当我在web上搜索PySide教程(例如http://qt-project.org/wiki/PySide-Newbie-Tutorials)时,它们都包含对super
的调用。我的问题是:我应该使用super
来编写PySide脚本吗?
当您拥有继承钻石时,super
似乎最有帮助,它倾向于以合理的方式解决多重继承的实例。PySide中是否经常使用super
,因为有大量这样的钻石案例,我将面对更为现实的复杂例子?[编辑:否:请参阅下面的答案。]
为什么我还要问?为什么不直接用super
来做呢?
我这样问是因为我用来学习Python的书(Lutz的《学习Python》)花了20多页来讨论super
这个主题,而且明确警告不要使用它。他建议新的Python用户在使用之前先使用更传统、更明确的方法(例如,参见第832页和第1041-1064页的学习Python,第5版)。他基本上把它描绘成一种非语言的,神秘的,很少实际需要的,新的风格,在刚开始的时候你应该非常小心地对待,并且认为它被有经验的用户过度使用。
此外,查看两个主要的基于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
用传统的方式实例化父类没有什么错,有些事情应该说是有利于它的。也就是说,使用
super
简化了子类的创建,以及将来对PySide代码的修改,人们似乎已经将后者作为压倒一切的因素。这并不是Pyside特有的,而是Python中面向对象的编程(正如Kos的优秀回答所指出的)。简化代码修改的潜力在于,在PySide中,必须根据其他
QtGui
对象(例如QtQui.QMainWindow
和QtGui.QWidget
)定义子类。此外,人们倾向于充分利用父类,这样似乎更容易使用super
,这样就不必每次更改父类时都更新init方法。因此,使用
super
来帮助解决多重继承的情况并不是问题,大多数人都认为这种情况最适合。相反,这是一个在in it中减少工作的问题,以防将来父类发生更改。以下是每个作者的回答,他们都写了我认为是很好的PySide教程:
作者1:
作者2:
好了,给你。这些好处并不是PySide特有的,而是编写子类/继承。
我不确定Lutz会说什么(也许使用
super
违反了“显式优于隐式”的格言),他似乎很犹豫是否支持使用super
。四年后更新 回想起来,这场辩论已经结束了,这个问题几乎很奇怪(这是我第一次问这个问题)。虽然过去有关于使用}的便利性已经得到了证明,并且使代码更易于维护。因为在Qt/Pyside/PyQt框架中,从更抽象的Qt类继承的使用非常普遍,这是一个不小的特性。当然,当你有疯狂的继承格时,你需要小心,但是坦白地说,自从我问这个问题以来,我从未遇到过这个问题,而且我目前在所有代码中都使用
super
的争论,但这些争论已经结束了。尤其是在Python 3中,{super
。可以说,它违反了“显式优于隐式”的格言,但“简单优于复杂”和“实用胜过纯粹”是这里最重要的因素(这里的实用方面是“可维护性计数”)。嗯,不错。但在我看来,它与Qt/PySide几乎没有关系。
首先,这两个有什么不同?如果你有简单的继承(也许不算“mixin”),那么行为上就没有区别。一个表面上的区别仍然存在-你不需要再命名你的基类-但是你必须命名同一个类。
当您具有多重继承时,差异就开始了。然后由
super()
组成的链调用此层次结构:可以通过
super()
调用轻松地执行此操作:不需要X和Y互相认识。这与method resolution order的概念有关,该概念允许在the Python docs中使用一种称为“协作多重继承”的编程风格。
如果有一个方法
Foo
,并且该方法在X和Y中的实现是建立在a的实现之上的,那么Z很容易依赖X和Y,而它们甚至不知道彼此。然而,这有一个重要的前提条件:Foo
在每个类中都有相同的(或至少是[兼容的])签名,正如最初定义它的A
接口所指定的那样。__init__
方法是特殊的:从技术上讲,它的工作方式与super
完全相同,但是!但是(通常情况下)对于子类,它有一个完全不同的签名。如果子类__init__
看起来不一样,那么super
不会给您任何超过显式基调用的东西,因为您无论如何都不能使用协作多任务。注意:Python在这方面非常不典型:在大多数OO语言中,构造函数属于类,而不是实例;换句话说,大多数语言依赖于它们的等价物
__new__
,根本没有__init__
。注2:我从未见过任何真正的代码依赖于协作多重继承。(单继承很容易为我做足够的意大利面;-))
此外,一些好的阅读:
[
相关问题 更多 >
编程相关推荐