Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Should one always add super().__init__() to the __init__? (http://www.velocityreviews.com/forums/t952844-should-one-always-add-super-__init__-to-the-__init__.html)

Ramchandra Apte 09-29-2012 01:27 PM

Should one always add super().__init__() to the __init__?
 
Should one always add super().__init__() to the __init__? The reason for this is the possibility of changing base classes (and forgetting to update the __init__).

Ramchandra Apte 09-29-2012 01:28 PM

Re: Should one always add super().__init__() to the __init__?
 
On Saturday, 29 September 2012 18:57:48 UTC+5:30, Ramchandra Apte wrote:
> Should one always add super().__init__() to the __init__? The reason for this is the possibility of changing base classes (and forgetting to update the __init__).


This is my first post so I may be breaching nettique.

Ian Kelly 09-29-2012 04:59 PM

Re: Should one always add super().__init__() to the __init__?
 
On Sat, Sep 29, 2012 at 7:27 AM, Ramchandra Apte <maniandram01@gmail.com> wrote:
> Should one always add super().__init__() to the __init__? The reason for this is the possibility of changing base classes (and forgetting to update the __init__).


As long as the class and its subclasses only use single inheritance,
it makes little difference, so if you think it will reduce the
maintenance burden, I would say go for it.

Steven D'Aprano 09-29-2012 05:17 PM

Re: Should one always add super().__init__() to the __init__?
 
On Sat, 29 Sep 2012 06:27:47 -0700, Ramchandra Apte wrote:

> Should one always add super().__init__() to the __init__? The reason for
> this is the possibility of changing base classes (and forgetting to
> update the __init__).


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



--
Steven

Devin Jeanpierre 09-29-2012 06:18 PM

Re: Should one always add super().__init__() to the __init__?
 
On Sat, Sep 29, 2012 at 1:17 PM, Steven D'Aprano
<steve+comp.lang.python@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 a good thing. We've gone from code that doesn't call the
initializer and leaves the object in a potentially invalid state
(silently!), to code that calls the initializer and then fails
(loudly).

-- Devin

Chris Angelico 09-29-2012 06:31 PM

Re: Should one always add super().__init__() to the __init__?
 
On Sun, Sep 30, 2012 at 3:17 AM, Steven D'Aprano
<steve+comp.lang.python@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.

ChrisA

Piet van Oostrum 09-29-2012 09:51 PM

Re: Should one always add super().__init__() to the __init__?
 
Chris Angelico <rosuav@gmail.com> writes:

> On Sun, Sep 30, 2012 at 3:17 AM, Steven D'Aprano
> <steve+comp.lang.python@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.


It is not necesarily calling the parent class. It calls the initializer
of the next class in the MRO order and what class that is depends on the
actual multiple inheritance structure it is used in, which can depend
on subclasses that you don't know yet. This makes it even worse.
--
Piet van Oostrum <piet@vanoostrum.org>
WWW: http://pietvanoostrum.com/
PGP key: [8DAE142BE17999C4]

Ramchandra Apte 09-30-2012 03:14 AM

Re: Should one always add super().__init__() to the __init__?
 
On Saturday, 29 September 2012 22:47:20 UTC+5:30, Steven D'Aprano wrote:
> On Sat, 29 Sep 2012 06:27:47 -0700, Ramchandra Apte wrote:
>
>
>
> > Should one always add super().__init__() to the __init__? The reason for

>
> > this is the possibility of changing base classes (and forgetting to

>
> > update the __init__).

>
>
>
> 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
>
>
>
>
>
>
>
> --
>
> Steven


I forgot something:
I meant super().__init__() or similar

Steven D'Aprano 09-30-2012 04:23 AM

Re: Should one always add super().__init__() to the __init__?
 
On Sat, 29 Sep 2012 20:14:10 -0700, Ramchandra Apte wrote:

> I forgot something:
> I meant super().__init__() or similar


What about it? Please try to remember that we can't read your mind and
don't know what you are thinking, we can only work from what you put in
writing.

There is no difference between super(Class, self).__init__ and
super().__init__ except that the second version only works in Python 3.



--
Steven

Steven D'Aprano 09-30-2012 04:37 AM

Re: Should one always add super().__init__() to the __init__?
 
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@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...sidered-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


All times are GMT. The time now is 11:02 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.