Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Should one always add super().__init__() to the __init__?

Reply
Thread Tools

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

 
 
Steven D'Aprano
Guest
Posts: n/a
 
      09-30-2012
On Sat, 29 Sep 2012 17:51:29 -0400, Piet van Oostrum wrote:

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


I don't quite follow you here. It sounds like you are saying that if you
have these classes:

# pre-existing classes
class A(object): pass
class B(object): pass

# your class
class C(A, B): pass

and somebody subclasses A or B, the MRO of C will change. That is not
actually the case as far as I can see.



--
Steven
 
Reply With Quote
 
 
 
 
Chris Angelico
Guest
Posts: n/a
 
      09-30-2012
On Sun, Sep 30, 2012 at 2:37 PM, Steven D'Aprano
<steve+> wrote:
> 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.


Yeah. Far as I'm concerned, subclassing should *always* involve
knowing the parent class. You needn't concern yourself with its
implementation (I can subclass dict without caring about the details
of hash randomization), but you have to be aware of its interface. And
if you change the base class without changing your method chaining,
you'd better be changing to a new base class that's equivalent to the
old one.

The advantage of super() is that you can substitute a subclass of X as
a new base class without changing anything. But you need to be sure
that the replacement base class obeys the Liskov Substitution
Principle.

ChrisA
 
Reply With Quote
 
 
 
 
Ramchandra Apte
Guest
Posts: n/a
 
      09-30-2012
On Sunday, 30 September 2012 09:53:45 UTC+5:30, Steven D'Aprano wrote:
> 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


When I said "super().__init__()" it could have been "super().__init__(size+67)" or whatever arguments are needed for __init__
 
Reply With Quote
 
Ian Kelly
Guest
Posts: n/a
 
      09-30-2012
On Sat, Sep 29, 2012 at 10:40 PM, Steven D'Aprano
<steve+> wrote:
> On Sat, 29 Sep 2012 17:51:29 -0400, Piet van Oostrum wrote:
>
>> 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.

>
> I don't quite follow you here. It sounds like you are saying that if you
> have these classes:
>
> # pre-existing classes
> class A(object): pass
> class B(object): pass
>
> # your class
> class C(A, B): pass
>
> and somebody subclasses A or B, the MRO of C will change. That is not
> actually the case as far as I can see.


The MRO of C will not change, but the class that follows C may be
different in the MRO of a subclass.
 
Reply With Quote
 
Ian Kelly
Guest
Posts: n/a
 
      09-30-2012
On Sat, Sep 29, 2012 at 10:55 PM, Ramchandra Apte
<> wrote:
> When I said "super().__init__()" it could have been "super().__init__(size+67)" or whatever arguments are needed for __init__


But if you change the base class, couldn't those arguments change?
Then you would have to change the call whether super is used or not.
I believe this is what Steven is getting at.
 
Reply With Quote
 
Ian Kelly
Guest
Posts: n/a
 
      09-30-2012
On Sat, Sep 29, 2012 at 10:37 PM, Steven D'Aprano
<steve+> wrote:
> [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.


I disagree. Most classes will not ever be used for multiple
inheritance, and the changes involved in "making sure that the
argument signatures are designed for cooperative use of super" are not
trivial. For one, it means not being able to use positional arguments
in __init__ methods. For two, the
receive-and-strip-off-keyword-arguments approach falls apart if you
have unrelated classes that take the same arguments. For
illustration, suppose you have the following two classes, both of
which use a required Frobnik object to perform their functions.


class A:
def __init__(self, frobnik, **kwargs):
super().__init__(**kwargs)
self._frobnik = frobnik
...

class B:
def __init__(self, frobnik, **kwargs):
super().__init__(**kwargs)
self._frobnik = frobnik
...

Even though these classes have been designed to be cooperative, they
cannot be inherited together. Whichever class is first in the MRO
will receive the frobnik argument and strip it off, and then the other
class's __init__ method will complain of a missing required argument.

There are solutions to this. For instance, you could make frobnik
optional in each class, each one relying on the other to receive the
frobnik argument if it is missing, but this complicates the
implementations and makes it difficult to detect in a timely manner if
the frobnik argument has actually not been supplied. Or you could
change the name of the argument in one of the classes, but then your
library users will complain of inconsistent naming.

What it boils down to is that classes that are expected to be used for
multiple inheritance should be designed to use super cooperatively,
but the majority of classes that you write should not have to deal
with these sorts of restrictions. Classes that will only ever be
singly inherited should be written normally and using whatever
superclass call style feels most appropriate.
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      09-30-2012
On Sun, 30 Sep 2012 00:08:03 -0600, Ian Kelly wrote:

> On Sat, Sep 29, 2012 at 10:40 PM, Steven D'Aprano
> <steve+> wrote:
>> On Sat, 29 Sep 2012 17:51:29 -0400, Piet van Oostrum wrote:
>>
>>> 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.

>>
>> I don't quite follow you here. It sounds like you are saying that if
>> you have these classes:
>>
>> # pre-existing classes
>> class A(object): pass
>> class B(object): pass
>>
>> # your class
>> class C(A, B): pass
>>
>> and somebody subclasses A or B, the MRO of C will change. That is not
>> actually the case as far as I can see.

>
> The MRO of C will not change, but the class that follows C may be
> different in the MRO of a subclass.


To quote a famous line from the movie Cool Hand Luke, "what we have here,
is a failure to communicate."

What do you mean by one class following another? Which class is it that
follows C? What subclass are you talking about, and what is it
subclassing?

I have absolutely no idea what you are trying to get across here, why you
think it is important, or whether it matches what Piet is trying to say.



--
Steven
 
Reply With Quote
 
Manuel Pégourié-Gonnard
Guest
Posts: n/a
 
      09-30-2012
Steven D'Aprano scripsit :

> On Sun, 30 Sep 2012 00:08:03 -0600, Ian Kelly wrote:
>
>> On Sat, Sep 29, 2012 at 10:40 PM, Steven D'Aprano
>> <steve+> wrote:
>>> On Sat, 29 Sep 2012 17:51:29 -0400, Piet van Oostrum wrote:
>>>
>>>> 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.
>>>
>>> I don't quite follow you here. It sounds like you are saying that if
>>> you have these classes:
>>>
>>> # pre-existing classes
>>> class A(object): pass
>>> class B(object): pass
>>>
>>> # your class
>>> class C(A, B): pass
>>>
>>> and somebody subclasses A or B, the MRO of C will change. That is not
>>> actually the case as far as I can see.

>>
>> The MRO of C will not change, but the class that follows C may be
>> different in the MRO of a subclass.

>
> To quote a famous line from the movie Cool Hand Luke, "what we have here,
> is a failure to communicate."
>
> What do you mean by one class following another? Which class is it
> that follows C? What subclass are you talking about, and what is it
> subclassing?
>

I think Piet's (and Ian's) point is, you can't assume that
super().__init__, written in a method of C, is always going to refer to
__init__ of the parent class of C, when a subclass of C is instanciated.

For example:

class C:
def __init__(self):
print("C init, calling C's parent init?")
super().__init__() # sic

class NotParentOfC:
def __init__(self):
print("NotParentOfC init")

class Sub(C, NotParentOfC):
pass

spam = Sub()

When Sub is instantiated, the line marked "sic" calls
NotParentOfC.__init, not object.__init__ (as if would if C was
instantiated).

--
Manuel Pégourié-Gonnard - http://people.math.jussieu.fr/~mpg/



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Should copying always be exact? Terry Pinnell DVD Video 5 04-05-2006 06:16 AM
Can/should one add expando properties to host-supplied objects? ytrewq Javascript 3 01-08-2005 11:29 AM
Trying to create a CSS box that is always is always the width of an image placed inside it (and no wider) Deryck HTML 4 06-22-2004 08:25 PM
Should 'public virtual' always become 'private virtual'? & using private inheritance qazmlp C++ 19 02-04-2004 12:37 AM
int i=5; p=(++i)*(++i)*(++i);should p always be 392? Liu Jin C Programming 3 07-09-2003 05:29 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57