eri*_*ric 13 python pyqt super pyside
短版(tl; dr)
我正在学习PySide,大多数在线教程都super用来初始化UI元素.这是重要的(即,更具可扩展性),还是品味问题?
澄清:当我在详细版本中更清楚时,这不是另一个通知线程,询问何时使用super(这已经在之前完成).相反,考虑到使用PySide教程的数量super,而不是<class>.__init__,我想如果用弄清楚super是PySide应用程序的标准?如果是这样,是因为super在使用PySide/PyQt时需要特别提到的(涉及解决继承问题)?或者这是品味问题.
详细版本
我是Python的新手,目前正在使用Zets教程学习PySide(http://zetcode.com/gui/pysidetutorial/firstprograms/).本教程的第二个示例包括:
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_())
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我从未使用过super.因此,我重写了上面的代码,成功地替换super了父类的更标准的显式调用:
QtGui.QWidget.__init__(self)
Run Code Online (Sandbox Code Playgroud)
但是,当我在网上搜索PySide教程时(例如,http://qt-project.org/wiki/PySide-Newbie-Tutorials ),它们都包括调用super.我的问题是:我应该super用于PySide脚本吗?
看来,super当你有继承的钻石,它倾向于解决多重继承的情况下,以合理的方式似乎是最有帮助的.是否super与PySide一起使用,因为这些钻石的案例占优势,我会面对更现实的复杂例子?[编辑:否:请参阅下面的答案.]
我为什么要问?为什么不直接使用super并完成它?
我在问,因为我用来学习Python的书(学习Python,由Lutz撰写)花了20多页关于这个主题super,并明确告诫不要使用它.他建议新的Python用户在使用它之前采用更传统,更明确的路线(例如,参见第832页,学习Python的第1041-1064页,第5版).他基本上将它描绘成一种非剧性的,神秘的,很少需要的新风格,刚开始时你应该非常谨慎地对待它,并认为它被有经验的用户过度使用.
此外,查看两个主要的PySide/PyQt项目(Spyder和pyqtgraph)的源代码,两者都没有使用super.One(Spyder)明确告诉贡献者出于兼容性原因而避免使用它(http://code.google.com/p/spyderlib/wiki/NoteForContributors).
注意我链接到下面一个密切相关的帖子,但是当你想要使用时super(当你有多个继承时),那里的答案会更一般地讨论.我的问题是PySide脚本是否证明甚至要求super长期使用,或者它是否更具Pythonic,并且出于兼容性原因更好地明确命名父类?还是味道问题?
如果它不受欢迎(正如我的初学者所说),为什么它在针对初学者的PySide教程中如此普遍?如果它有任何区别,那么编写这些教程的人似乎是经验丰富的Java程序员,或者迎合这些程序员.我不是.
相关话题
http://www.riverbankcomputing.com/pipermail/pyqt/2008-January/018320.html
嗯,很好.但IMO与Qt/PySide几乎没有关系.
首先,这两者有何不同?如果你有简单的继承(也许不算"mixins"),那么行为就没有区别了.化妆品差异仍然存在 - 您不需要再次命名基类 - 但您必须命名同一个类.
当您有多个继承时,差异就会开始.然后是super()这个层次结构的一系列调用:
A
/ \
X Y
\ /
Z
Run Code Online (Sandbox Code Playgroud)
通过super()电话可以很容易地进行:
A
\
X --- Y
\
Z
Run Code Online (Sandbox Code Playgroud)
不需要X和Y相互了解.这涉及方法解析顺序的概念,它允许在Python文档中称为"协作多重继承"的编程风格.
如果该方法的FooX和Y中的方法和实现基于A的实现构建,那么Z很容易依赖于X和Y,而他们甚至不知道彼此.然而,这有一个重要的前提条件:Foo在每个类中具有相同(或至少[兼容])签名,如A最初定义的接口所指定的那样.
该__init__方法是特殊的:在技术上它正好与相同的方式工作super,但!但是(通常情况下),对于子类,它具有完全不同的签名.如果子类' __init__看起来不同,那么super就不会给你任何超过显式基本调用的东西,因为你无论如何都无法使用协作式多任务处理.
注意:Python在这方面非常不典型:在大多数OO语言中,构造函数属于类,而不是实例; 换句话说,大多数语言都依赖于它们的等价物__new__而根本没有__init__.
注2:我从未见过任何依赖合作多重继承的真实代码.(单遗传很容易为我制作足够的意大利面;-))
还有一些好的阅读:
[
在研究了这个问题之后我得到了临时答案,上周与PySide合作,并通过电子邮件发送了两篇关于PySide的教程的作者(其中一篇使用了super,另一篇没有,在教程中).
也就是说,使用super很大程度上是一种品味问题,因为以传统方式实例化父类没有任何问题,并且有些事情可以说是有利于它.然而,至少在表面上,使用QtGui似乎简化了对一个人的PySide代码的未来修改,人们似乎已经把它作为最重要的因素.
简化代码修改的可能性是因为在PySide中,通常基于QtGui对象(例如,QtQui.QMainWindow和QtGui.QWidget)定义子类.此外,人们倾向于使用他们的父类足够多,以便使用起来更容易super,这样您每次更换父母时都不必更新__init__功能.
所以这不是super用来帮助解决多重继承案例的问题,大多数人都认为它可能是最适合的.相反,如果您的父类将来发生变化,则需要在__init__中减少工作量.
以下是每位作者的回复,他们都写了我认为好的PySide教程:
作者1:
我认为这是一个品味问题.早期教程(PyQt和PySide)使用.init和后来我切换到super().我个人更喜欢super().
作者2:
人们使用super代替的原因.init(...)是为了避免在更改父类的内容时进行更改,例如,如果从QVBoxLayout切换到QHBoxLayout,则只需在类定义行中更改它,而不是在init方法中更改它.
所以你有它.不确定这是否真的特定于PySide,或更普遍地编写子类.
我不确定Lutz,他似乎非常犹豫是否支持使用super,会说(也许使用super违反了'Explicit比隐含'更好,对于初学者而言).当我试图更好地理解他对函数的关注时,我将在此上发布更多内容.
| 归档时间: |
|
| 查看次数: |
8710 次 |
| 最近记录: |