[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