为什么 super 在 PySide/PyQt 中使用得如此之多? [英] Why is super used so much in PySide/PyQt?

查看:63
本文介绍了为什么 super 在 PySide/PyQt 中使用得如此之多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短版本 (tl;dr)

我正在学习 PySide,大多数在线教程使用 super 来初始化 UI 元素.这是否重要(即更具可扩展性),还是品味问题?

澄清:正如我在详细版本中更清楚地说明的那样,这不是另一个询问何时使用 super 的通用线程(这已经完成了).相反,考虑到使用 super 而不是 .__init__ 的 PySide 教程的数量,我试图弄清楚是否使用 super是 PySide 应用程序的标准吗?如果是这样,是不是因为在使用 PySide/PyQt 时会出现很多需要 super 的情况(涉及解析继承)?或者是品味问题.

详细版本

我是 Python 新手,目前正在使用 Zets 教程学习 PySide (http://zetcode.com/gui/pysidetutorial/firstprograms/).本教程中的第二个示例包括:

from PySide import QtGui类示例(QtGui.QWidget):def __init__(self):超级(例如,自我).__init__()self.initUI()定义 initUI(self):self.setGeometry(300,300,250,150)self.setWindowTitle("PySide 101: Window the First!")自我展示()app=QtGui.QApplication(sys.argv)前=示例()sys.exit(app.exec_())

这很好用,但我从未使用过 super.因此,我重写了上面的代码,成功地用更标准的父类显式调用替换了 super:

QtGui.QWidget.__init__(self)

但是当我在网上搜索 PySide 教程时(例如,http://qt-project.org/wiki/PySide-Newbie-Tutorials),它们全部包括对super的调用.我的问题是:我应该使用 super 来编写 PySide 脚本吗?

super 似乎在您拥有继承钻石时最有帮助,它倾向于以合理的方式解决多重继承的实例.super 是否在 PySide 中被大量使用,因为这样的钻石案例占优势,我将面临更现实的复杂示例?

我为什么要问?为什么不直接使用 super 就可以了?

我之所以这么问是因为我用来学习 Python 的书(学习 Python,Lutz 着)在 super 的主题上花费了 20 多页,并且明确警告不要使用它.他建议 Python 新用户在弄乱它之前先走更传统、更明确的路线(例如,参见 Learning Python,第 5 版的第 832 页和第 1041-1064 页).他基本上把它描绘成一种非 Python 风格的、神秘的、很少真正需要的新风格,刚开始时你应该非常谨慎地对待它,并认为它被有经验的用户过度使用.

再看两个主要的基于 PySide/PyQt 的项目(Spyder 和 pyqtgraph)的源代码,都没有使用 super.一个 (Spyder) 明确告诉贡献者出于兼容性原因避免使用它 (http://code.google.com/p/spyderlib/wiki/NoteForContributors" rel="noreferrer">http://code.google.com/p/spyderlib/wiki/NoteForContributors).google.com/p/spyderlib/wiki/NoteForContributors).

注意我链接到下面一个密切相关的帖子,但那里的答案更一般地讨论了您何时想要使用 super (当您有多重继承时).我的问题是,从长远来看,PySide 脚本是否证明或什至需要使用 super ,或者是否更 Pythonic 并且出于兼容性原因更好地明确命名父类?还是口味问题?

如果它不受欢迎(正如我的初学者书所建议的那样),为什么它在针对初学者的 PySide 教程中如此普遍?如果这有什么不同,那么编写这些教程的人似乎都是经验丰富的 Java 程序员,或者是迎合这些程序员的需求.我不是.

相关主题

http://www.riverbankcomputing.com/pipermail/pyqt/2008 年 1 月/018320.html

在 PyQt4 中使用 __init__ 的不同方式

了解 Python super() 和 __init__() 方法

解决方案

以传统方式实例化父类并没有错,有些话要说支持它.也就是说,使用 super 简化了子类的创建,以及未来对 PySide 代码的修改,人们似乎已经将后者视为最重要的因素.这不是 Pyside 特有的,而是更普遍地针对 Python 中的面向对象编程(正如 Kos 的优秀回答中所指出的那样).

简化代码修改的潜力来自于在 PySide 中,需要根据其他 QtGui 对象(例如,QtQui.QMainWindowQtGui.QWidget).此外,人们倾向于对他们的父类进行足够的讨论,因此使用 super 似乎更容易,这样您就不必每次更改父类时都更新 __init__ 方法.>

所以这不是使用 super 来帮助解决多重继承的问题,大多数人认为它可能是最适合的情况.而是在 __init__ 中做更少的工作,以防将来您的父类发生变化.

以下是每位作者的回复,他们都写了我认为不错的 PySide 教程:

作者 1:

<块引用>

我认为这是一个品味问题.早期教程(PyQt 和 PySide)使用 .init ,后来我切换到 super().我个人更喜欢 super().

作者 2:

<块引用>

人们使用 super 而不是 .init(...) 的原因是如果您更改父类的内容,请避免进行更改,例如如果你从QVBoxLayout切换到QHBoxLayout,你只需要改变它在类定义行中,而不是在 init 方法中作为嗯.

所以你有它.并不是这些好处并不是 PySide 特有的,而是更普遍地编写子类/继承.

我不确定 Lutz 会说什么,他似乎对支持使用 super 犹豫不决(也许使用 super 违反了显式优于隐式' 格言).

四年后更新
回想起来,这场辩论已经结束了,这个问题几乎很古怪(这是我在 SO 的第一个问题).虽然曾经有关于 super 的使用的争论,但这些争论已经结束了.尤其是在 Python 3 中 super 的便利性已经得到证明,它只会让您的代码更易于维护.因为在 Qt/Pyside/PyQt 框架中,从更抽象的 Qt 类继承的使用无处不在,这是一个不小的特性.当然,当你有疯狂的继承格时你需要小心,但坦率地说,自从我问这个问题后,我真的从来没有遇到过这个问题,而且我目前在我所有的代码中都使用了 super.它可以说违反了显式优于隐式"的格言,但简单优于复杂"和实用性胜过纯度"是这里的首要因素(这里的实际方面是可维护性计数").

Short version (tl;dr)

I am learning PySide, and most online tutorials use super to initialize UI elements. Is this important (i.e., more scalable), or is it a matter of taste?

Clarification: as I make more clear in the detailed version, this is not another generic thread asking when to use super (this has been done before). Rather, given the number of PySide tutorials that use super instead of <class>.__init__, I am trying to figure out if using super is standard in PySide applications? If so, is it because the circumstances where super is called for (involving resolving inheritances) come up a lot specifically in the use of PySide/PyQt? Or is it a matter of taste.

Detailed version

I am new to Python, and presently learning PySide using Zets tutorial (http://zetcode.com/gui/pysidetutorial/firstprograms/). The second example in the tutorial includes:

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_())    

This works fine, but I have never used super. Hence, I rewrote the above code, successfully replacing super with more standard explicit invocation of the parent class:

QtGui.QWidget.__init__(self)

But as I search the web for PySide tutorials (e.g., http://qt-project.org/wiki/PySide-Newbie-Tutorials), they all include calls to super. My question is: should I use super for PySide scripting?

It seems that super seems most helpful when you have inheritance diamonds, that it tends to resolve instances of multiple inheritance in a reasonable way. Is super used a lot with PySide because there is a preponderance of cases of such diamonds that I will confront with more realistic complicated examples? [Edit: No: see my answer below.]

Why am I even asking? Why not just use super and be done with it?

I am asking because the book I am using to learn Python (Learning Python, by Lutz) spends over 20 pages on the topic of super, and explicitly cautions against using it. He suggests that new Python users go with the more traditional, explicit route before messing with it (e.g., see page 832, and pages 1041-1064 of Learning Python, 5th Edition). He basically paints it as a nonPythonic, arcane, rarely actually needed, new style that you should treat with great caution when just starting out, and thinks it is overused by experienced users.

Further, looking at the source code of two major PySide/PyQt based projects (Spyder and pyqtgraph), neither uses super. One (Spyder) explicitly tells contributors to avoid using it for compatibility reasons (http://code.google.com/p/spyderlib/wiki/NoteForContributors).

Note I link to a closely related post below, but the answer there discusses more generally when you would want to use super (when you have multiple inheritance). My question is whether PySide scripting justifies, or even requires, the use of super in the long term, or whether it is more Pythonic, and better for compatibility reasons, to explicitly name parent classes? Or is it a matter of taste?

If it is frowned upon (as my beginner book suggests) why is it so ubiquitous in PySide tutorials aimed at beginners? If it makes any difference, it seems the people writing these tutorials are seasoned Java programmers, or catering to such programmers. I am not.

Related topics

http://www.riverbankcomputing.com/pipermail/pyqt/2008-January/018320.html

Different ways of using __init__ for PyQt4

Understanding Python super() with __init__() methods

解决方案

There is nothing wrong with instantiating parent classes in the traditional way, and some things to be said in favor of it. That said, using super simplifies the creation of subclasses, and the future modifications of one's PySide code, and people seem to have latched onto the latter as the overriding factor. This is not specific to Pyside, but to object-oriented programming in Python more generally (as pointed out in Kos's excellent answer).

The potential for simplification of code modification comes because within PySide it is necessary for things to work to define subclasses based on other QtGui objects (e.g., QtQui.QMainWindow and QtGui.QWidget). Further, people tend to futz around with their parent classes enough so that it seems easier to just use super, so that you you don't have to update your __init__ method every time you change parents.

So it isn't a matter of using super to help resolve cases of multiple inheritance, the case where most people agree it is probably best suited. Rather, it is a matter of doing less work within __init__ in case your parent class changes in the future.

Here are the responses from each author, both of whom wrote what I consider to be good PySide tutorials:

Author 1:

I think it is a matter of taste. Earlier tutorials (PyQt and PySide) used .init and later I switched to super(). I personally prefer super().

Author 2:

The reason people use super instead of .init(...) is to avoid making changes if you change what the parent class is, e.g. if you switch from QVBoxLayout to QHBoxLayout, you only have to change it in the class definition line, rather than in the init method as well.

So there you have it. Not these benefits aren't really specific to PySide, but to writing subclasses/inheritance more generally.

I'm not sure what Lutz, who seems very hesitant to endorse the use of super, would say (perhaps using super violates the 'Explicit is better than implicit' maxim).

Update Four Years Later
In retrospect, this debate is sort of over and this question is almost quaint (this was my first question at SO). While there used to be debate about the use of super, these debates are sort of over. Especially in Python 3 super's convenience has proven itself and just makes your code easier to maintain. Because in Qt/Pyside/PyQt framework the use of inheritance from more abstract Qt classes is ubiquitous, this is no small feature. Sure, you will need to be careful when you have crazy lattices of inheritance, but frankly since I asked this question, I have literally never run into this problem, and I currently use super in all my code. It arguably violates the "explicit is better than implicit" maxim, but "Simple is better than complex" and "practicality beats purity" are the overriding factors here (the practical aspect here is "maintainability counts").

这篇关于为什么 super 在 PySide/PyQt 中使用得如此之多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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