MyTetra Share
Делитесь знаниями!
How to invoke the super constructor?
Время создания: 16.07.2018 10:19
Текстовые метки: python oop parent constructor super
Раздел: Python

class A:

def __init__(self):

print "world"


class B(A):

def __init__(self):

print "hello"


B()

hello

In all other languages I've worked with the super constructor is invoked implicitly. How does one invoke it in Python? I would expect super(self) but this doesn't work.


python class inheritance constructor superclass

shareimprove this question

edited Feb 7 at 15:33


Vadim Kotov

3,95852947

asked Mar 8 '10 at 4:35


Mike

20.4k62150196

Possible duplicate of Chain-calling parent constructors in python – Trevor Boyd Smith Oct 19 '16 at 13:22

add a comment

5 Answers

active oldest votes

up vote

251

down vote

accepted

super() returns a parent-like object in new-style classes:


class A(object):

def __init__(self):

print "world"


class B(A):

def __init__(self):

print "hello"

super(B, self).__init__()


B()

shareimprove this answer

edited Dec 26 '16 at 22:51


martineau

60.6k785158

answered Mar 8 '10 at 4:43


Ignacio Vazquez-Abrams

550k9310121118

49

just of curiosity why does super(B,self) require both B and self to be mentioned? isn't this redundant? shouldn't self contain a reference to B already? – Mike Mar 8 '10 at 4:48

82

No, because self might actually be an instance of C, a child of B. – Ignacio Vazquez-Abrams Mar 8 '10 at 4:50

4

@Luc: That's because the class was declared incorrectly. See my answer. – Ignacio Vazquez-Abrams Jul 21 '15 at 15:20

8

With respect to the documentation of super(), you should be able to write super().__init__() wothout arguments. – JojOatXGME Apr 12 '16 at 15:02

7

@JojOatXGME: In 3.x, yes. 2.x still needs the arguments. – Ignacio Vazquez-Abrams Apr 12 '16 at 15:45

show 12 more comments

up vote

108

down vote

In line with the other answers, there are multiple ways to call super class methods (including the constructor), however in Python-3.x the process has been simplified:


Python-2.x


class A(object):

def __init__(self):

print "world"


class B(A):

def __init__(self):

print "hello"

super(B, self).__init__()

Python-3.x


class A(object):

def __init__(self):

print("world")


class B(A):

def __init__(self):

print("hello")

super().__init__()

super() is now equivalent to super(<containing classname>, self) as per the docs.


shareimprove this answer

edited Mar 17 '17 at 5:40

answered Oct 17 '15 at 20:17


Aidan Gomez

2,65341942

add a comment

up vote

48

down vote

With Python 2.x old-style classes it would be this:


class A:

def __init__(self):

print "world"


class B(A):

def __init__(self):

print "hello"

A.__init__(self)

shareimprove this answer

edited Jul 21 '15 at 15:59

answered Mar 8 '10 at 4:48


Gabe

68.9k7111197

This won't work for new style classes? – kdbanman Jun 2 '15 at 19:45

4

@kdbanman: This will work with new-style classes, but one of the reasons to use new-style classes is to not have to do it this way. You can use super and not have to directly name the class you're inheriting from. – Gabe Jun 3 '15 at 0:58

add a comment

up vote

30

down vote

One way is to call A's constructor and pass self as an argument, like so:


class B(A):

def __init__(self):

A.__init__(self)

print "hello"

The advantage of this style is that it's very clear. It call A's constructor. The downside is that it doesn't handle diamond-shaped inheritance very well, since you may end up calling the shared base class's constructor twice.


Another way is to use super(), as others have shown. For single-inheritance, it does basically the same thing as letting you call the parent's constructor.


However, super() is quite a bit more complicated under-the-hood and can sometimes be counter-intuitive in multiple inheritance situations. On the plus side, super() can be used to handle diamond-shaped inheritance. If you want to know the nitty-gritty of what super() does, the best explanation I've found for how super() works is here (though I'm not necessarily endorsing that article's opinions).


shareimprove this answer

edited Mar 1 '13 at 23:02


Jim Ferrans

20.9k104777

answered Mar 8 '10 at 5:01


Daniel Stutzbach

45.4k116773

Is there any need to call A's constructor like this when it doesn't take any variable(ignoring self) as an argument? I mean the code works fine without A.__init__(self) line. – Alpha Romeo May 10 at 13:41

add a comment

up vote

3

down vote

I use the following formula that extends previous answers:


class A(object):

def __init__(self):

print "world"


class B(A):

def __init__(self):

print "hello"

super(self.__class__, self).__init__()


B()

This way you don't have to repeat the name of the class in the call to super. It can come handy if you are coding a large number of classes, and want to make your code in the constructor methods independent of the class name.


shareimprove this answer

answered Nov 20 '15 at 10:46


lackadaisical

758813

5

But you will get infinitive recursion if decide to extend B with C, and self.__class__ points to C(B) instead of B(A), so super(self.__class__, self) points back to B instead of A. – dened Jun 1 '16 at 8:11

7

This will lead to infinite recursion errors when you subclass B. Do not use self.__class__ or type(self), either pass in an explicit class (B here) or, in Python 3, use super() without arguments. – Martijn Pieters♦ Sep 30 '16 at 16:25

Так же в этом разделе:
 
MyTetra Share v.0.53
Яндекс индекс цитирования