Should one always add super().__init__() to the __init__?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Sep 30 00:37:22 EDT 2012


On Sun, 30 Sep 2012 04:31:48 +1000, Chris Angelico wrote:

> On Sun, Sep 30, 2012 at 3:17 AM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote:
>> No. Only add code that works and that you need. Arbitrarily adding
>> calls to the superclasses "just in case" may not work:
>>
>> py> class Spam(object):
>> ...     def __init__(self, x):
>> ...             self.x = x
>> ...             super(Spam, self).__init__(x) ...
>> py> x = Spam(1)
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>>   File "<stdin>", line 4, in __init__
>> TypeError: object.__init__() takes no parameters
> 
> That's because you're subclassing something that doesn't take parameters
> and giving it parameters. Of course that won't work. The normal and
> logical thing to do is to pass on only the parameters that you know the
> parent class expects... but that implies knowing the parent, so it's
> kinda moot.

Which is exactly my point -- you can't call the superclass "just in case" 
it changes, because you don't know what arguments the new superclass or 
classes expect. You have to tailor the arguments to what the parent 
expects, and even whether or not you have to call super at all.[1]

super() is not some magic command "don't bother me with the details, just 
make method overriding work". You have to actually think about what you 
are overriding. You can't expect to take a class that inherits from dict 
and change it to inherit from collections.defaultdict and have super 
magically sort out the differences in __init__.

The usual advise given for using super is:

* the method being called by super() needs to exist
* the caller and callee need to have a matching[2] argument signature
* and every occurrence of the method needs to use super()

If all three conditions apply, then yes, you should use super. Otherwise, 
perhaps not.

For further discussion and practical examples, see:

http://rhettinger.wordpress.com/2011/05/26/super-considered-super/


For a contrary argument, or at least a look at how NOT to use super, see:

https://fuhm.net/super-harmful/

which makes the mistake of blaming super() for mistakes made by people 
who don't use it correctly. Note that the author has back-peddled from 
his original argument that super was actively harmful to a less 
provocative argument that "you can't use super" (except you actually can: 
if you read past the first paragraph, the author tells you exactly what 
you need to do to use super correctly).




[1] You *should* call super, unless you have an excellent reason not to, 
so that your class doesn't break multiple-inheritance. But you need to do 
so with care making sure that the argument signatures are designed for 
cooperative use of super.

[2] Matching in this case does not necessarily mean identical.

-- 
Steven



More information about the Python-list mailing list