Why Is Super Used So Much In PySide/PyQt?
Solution 1:
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").
Solution 2:
Hm, nice one. But IMO it's only barely related to Qt/ PySide.
First, how are these two different? If you have simple inheritance (perhaps not counting "mixins"), then there's no difference in behaviour. A cosmetic difference remains- you don't need to name your base class again - but you do have to name the same class.
The differences start when you have multiple inheritance. Then a chain of super()
calls for this hierarchy:
A
/ \
X Y
\ /
Z
can easily proceed like this through super()
calls:
A
\
X --- Y
\
Z
without the need of X and Y knowing each other. This relates to the concept of method resolution order that allows a style of programming called "cooperative multiple inheritance" in the Python docs.
If there's a method Foo
and implementations in X and Y of that method build upon A's implementation, then Z is easily able to rely on both X and Y without them knowing even about each other. This, however, has an important precondition: Foo
has the same (or at least [compatible]) signature in every class, as specified by A
's interface where it's initially defined.
The __init__
method is special: technically it works in exactly the same way with super
, but! but (more often than not) for subclasses it has a totally different signature. If the subclass' __init__
looks different, then super
won't give you anything over explicit base call because you aren't able to use cooperative multitasking anyway.
Note: Python is very atypical in this respect: in most OO languages constructors belong to the class, rather than the instances; in other words most languages rely on their equivalents of __new__
and don't have __init__
at all.
Note 2: I have never seen any real code that would rely of cooperative multiple inheritance. (Single inheritance easily makes enough spaghetti for me ;-))
Also, some good reading:
- Method resolution order - what's it all about
- Python's Super is nifty, but you can't use it
[
Post a Comment for "Why Is Super Used So Much In PySide/PyQt?"