|
|||||||
How to invoke the super constructor?
Время создания: 16.07.2018 10:19
Текстовые метки: python oop parent constructor super
Раздел: Python
Запись: Velonski/mytetra-database/master/base/1531718370jomxyvurlr/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
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 |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|