[Python-Dev] super() harmful?
Guido van Rossum
gvanrossum at gmail.com
Wed Jan 5 03:02:17 CET 2005
[Josiah]
> Agreed. While it seems that super() is the 'modern paradigm' for this,
> I have been using base.method(self, ...) for years now, and have been
> quite happy with it. After attempting to convert my code to use the
> super() paradigm, and having difficulty, I discovered James Knight's
> "Python's Super Considered Harmful" (available at
> http://www.ai.mit.edu/people/jknight/super-harmful/ ), wherein I
> discovered how super really worked (I should have read the documention
> in the first place), and reverted my changes to the base.method version.
I think that James Y Knight's page misrepresents the issue. Quoting:
"""
Note that the __init__ method is not special -- the same thing happens
with any method, I just use __init__ because it is the method that most
often needs to be overridden in many classes in the hierarchy.
"""
But __init__ *is* special, in that it is okay for a subclass __init__
(or __new__) to have a different signature than the base class
__init__; this is not true for other methods. If you change a regular
method's signature, you would break Liskov substitutability (i.e.,
your subclass instance wouldn't be acceptable where a base class
instance would be acceptable).
Super is intended for use that are designed with method cooperation in
mind, so I agree with the best practices in James's Conclusion:
"""
* Use it consistently, and document that you use it,
as it is part of the external interface for your class, like it or not.
* Never call super with anything but the exact arguments you received,
unless you really know what you're doing.
* When you use it on methods whose acceptable arguments can be
altered on a subclass via addition of more optional arguments,
always accept *args, **kw, and call super like
"super(MyClass, self).currentmethod(alltheargsideclared, *args,
**kwargs)".
If you don't do this, forbid addition of optional arguments in subclasses.
* Never use positional arguments in __init__ or __new__.
Always use keyword args, and always call them as keywords,
and always pass all keywords on to super.
"""
But that's not the same as calling it harmful. :-(
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list