788

When creating a simple object hierarchy in Python, I'd like to be able to invoke methods of the parent class from a derived class. In Perl and Java, there is a keyword for this (super). In Perl, I might do this:

package Foo;

sub frotz {
    return "Bamf";
}

package Bar;
@ISA = qw(Foo);

sub frotz {
   my $str = SUPER::frotz();
   return uc($str);
}

In Python, it appears that I have to name the parent class explicitly from the child. In the example above, I'd have to do something like Foo::frotz().

This doesn't seem right since this behavior makes it hard to make deep hierarchies. If children need to know what class defined an inherited method, then all sorts of information pain is created.

Is this an actual limitation in python, a gap in my understanding or both?

SuperStormer
  • 4,997
  • 5
  • 25
  • 35
jjohn
  • 9,708
  • 4
  • 20
  • 21
  • 3
    I think the naming of the parent class isn't such a bad idea. It can help when the child class inherits from more than one parent, since you explicitly name the parent class. –  Apr 30 '09 at 02:12
  • 9
    While an option to name a class is not a bad idea, being forced to do so certainly is. – johndodo Jul 09 '14 at 12:14
  • Be aware of the changes in super handling between Python 2 and Python 3 [https://www.python.org/dev/peps/pep-3135/](https://www.python.org/dev/peps/pep-3135/). Naming the class is no longer required (although may still be a god idea, at least sometimes). – jwpfox Dec 28 '16 at 21:26

16 Answers16

1004

Use the super() function:

class Foo(Bar):
    def baz(self, **kwargs):
        return super().baz(**kwargs)

For Python < 3, you must explicitly opt in to using new-style classes and use:

class Foo(Bar):
    def baz(self, arg):
        return super(Foo, self).baz(arg)
jason m
  • 6,519
  • 20
  • 69
  • 122
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • 65
    Can you not also do "return Bar.baz(self, arg)"? If so, which would be better? –  Apr 30 '09 at 02:09
  • 21
    Yes, you can, but the OP was asking how to do it without explicitly naming the superclass at the call site (Bar, in this case). – Adam Rosenfield Apr 30 '09 at 02:13
  • 13
    super() is weird with multiple inheritance. It calls to the "next" class. That might be the parent class, or might be some completely unrelated class which appears elsewhere in the hierarchy. – Steve Jessop May 01 '09 at 15:41
  • 2
    Steve, most of the time it does what is most reasonable, for example when confronting the http://en.wikipedia.org/wiki/Diamond_problem. – Turion Jul 24 '12 at 21:28
  • Here's a version that proxies only certain requests, otherwise it just loads the file from disk by calling super: https://gist.github.com/grav/ad389981e0d7c1dd79ef0567760ce54b – Grav Jul 04 '16 at 09:14
  • 8
    I use Python 2.x, and I get "Error: must be type, not classobj" when I do this – Chris F Dec 14 '16 at 20:30
  • 35
    The syntax `super(Foo, self)` is for Python 2.x correct? In Python 3.x, the `super()` is preferred correct? – Trevor Boyd Smith Apr 24 '17 at 12:18
  • 2
    @SteveJessop, the order precedence of inheritence is very well described in this article: https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ – alpha_989 Apr 05 '18 at 17:20
  • 1
    super is not a function but a class. See `help(super)` – Pierre Thibault Apr 17 '18 at 14:33
  • 1
    @ChrisF You need new style classes. That means your base class must explicitly subclass object. i.e. class Bar(object) – Gopoi Apr 06 '19 at 19:36
  • Instead of `super().baz(arg)`, I use `Bar.baz(self, arg)` which is more flexible and lets me call multiple base methods or constructors if I wanted to. – nurettin Jun 09 '20 at 15:14
  • 2
    @nurettin: If all the bases use `super()`, they also call multiple base methods. `Bar.baz` is more explicit, and flexible, but it means even tighter coupling; consistent use of `super()` lets you consistently invoke all versions of a method without naming the classes or risking not calling a given method or calling it more than once. – ShadowRanger Nov 05 '20 at 18:19
  • @ShadowRanger yes it increases coupling where you may one day want to derive from some other class instead and still keep your code working. I'd say this is pretty rare, though. – nurettin Nov 05 '20 at 18:27
  • Note similarity to perl Moose, which also offers a `super()` method – bytepusher Jul 05 '21 at 19:51
  • What if a variable generated in the parent class method needs to be used in the same but extended method in the child class? The code below does not work ```class Parent(): def print(): self.a = 1 print('a= ', a) class Child(Parent): def print(): super().print() b = a + 1 print('b= ', b) kid = Child() kid.print() ``` – Jayyu Aug 22 '22 at 01:33
165

Python also has super as well:

super(type[, object-or-type])

Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.

Example:

class A(object):     # deriving from 'object' declares A as a 'new-style-class'
    def foo(self):
        print "foo"

class B(A):
    def foo(self):
        super(B, self).foo()   # calls 'A.foo()'

myB = B()
myB.foo()
MaBe
  • 91
  • 5
Jay
  • 41,768
  • 14
  • 66
  • 83
  • 9
    Better example than Adam's because you demonstrated using a new-style class with the object base class. Just missing the link to new-style classes. – Samuel Jan 09 '15 at 21:41
  • Adam's has the benefit of showing both Python2 and Python3 forms. While this example works with both versions, the "new-style class" business and the arguments to `super()` are artifacts of Python2 - see Adam's Python 3 version for cleaner code example (in Python3, all classes are now new-style classes, so there is no need to explicitly inherit from `object`, and `super()` does not require the class and `self` arguments, it's just `super()`). – PaulMcG Jul 06 '21 at 11:11
  • 1
    Is there any difference between calling just super().foo() instead of super(B, self).foo()? Both seem be working. – Ravindra S May 23 '22 at 14:02
  • @RavindraS The super function without arguments only works from within a method, while the two-argument version can be used in free functions as well. See the end of the [doc](https://docs.python.org/3/library/functions.html#super). – Zoltán Csáti Apr 27 '23 at 16:16
90
ImmediateParentClass.frotz(self)

will be just fine, whether the immediate parent class defined frotz itself or inherited it. super is only needed for proper support of multiple inheritance (and then it only works if every class uses it properly). In general, AnyClass.whatever is going to look up whatever in AnyClass's ancestors if AnyClass doesn't define/override it, and this holds true for "child class calling parent's method" as for any other occurrence!

industryworker3595112
  • 3,419
  • 2
  • 14
  • 18
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
89

Python 3 has a different and simpler syntax for calling parent method.

If Foo class inherits from Bar, then from Bar.__init__ can be invoked from Foo via super().__init__():

class Foo(Bar):

    def __init__(self, *args, **kwargs):
        # invoke Bar.__init__
        super().__init__(*args, **kwargs)
Arun Ghosh
  • 7,634
  • 1
  • 26
  • 38
75

Many answers have explained how to call a method from the parent which has been overridden in the child.

However

"how do you call a parent class's method from child class?"

could also just mean:

"how do you call inherited methods?"

You can call methods inherited from a parent class just as if they were methods of the child class, as long as they haven't been overwritten.

e.g. in python 3:

class A():
  def bar(self, string):
    print("Hi, I'm bar, inherited from A"+string)

class B(A):
  def baz(self):
    self.bar(" - called by baz in B")

B().baz() # prints out "Hi, I'm bar, inherited from A - called by baz in B"

yes, this may be fairly obvious, but I feel that without pointing this out people may leave this thread with the impression you have to jump through ridiculous hoops just to access inherited methods in python. Especially as this question rates highly in searches for "how to access a parent class's method in Python", and the OP is written from the perspective of someone new to python.

I found: https://docs.python.org/3/tutorial/classes.html#inheritance to be useful in understanding how you access inherited methods.

Ben
  • 913
  • 6
  • 16
  • @gizzmole in what situation does this not work? I'm happy to add any caveats or warnings which are relevant, but I couldn't figure out how the link you posted was relevant to this answer. – Ben Aug 09 '18 at 13:12
  • @Ben Sorry, I did not read your answer carefully enough. This answer does not answer the question on how to overload functions, but answers a different question. I deleted my initial comment. – gizzmole Aug 09 '18 at 13:42
  • 1
    @gizzmole ah, no worries. I realise that this answer does not apply to overloading functions, however the question does not explicitly mention overloading (though the perl example given does show a case of overloading). The vast majority of other answers cover overloading - this one is here for those people who don't need it. – Ben Aug 09 '18 at 14:55
  • @Ben what if I want to call B().baz() from another class named 'C' using vars defined in C?. I tried doing B().baz() in class C, where self.string is another val. It gave me none, when I executed – joey Sep 25 '18 at 17:07
  • @joey I'm not sure what you are trying to do, or if it is within the scope of this question. String is a local variable - setting ```self.string``` will not do anything. In class C you could however still call ```B().bar(string)``` – Ben Sep 26 '18 at 17:04
  • Exactly what I was looking for! The other answers gave me the (wrong) impression that I always had to call `super()` when using a parent class's methods. – codeananda Feb 02 '23 at 11:56
32

Here is an example of using super():

#New-style classes inherit from object, or from another new-style class
class Dog(object):

    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self):
        self.moves.append('walk')
        self.moves.append('run')

    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super(Superdog, self).moves_setup()
        self.moves.append('fly')

dog = Superdog('Freddy')
print dog.name # Freddy
dog.moves_setup()
print dog.get_moves() # ['walk', 'run', 'fly']. 
#As you can see our Superdog has all moves defined in the base Dog class
yesnik
  • 4,085
  • 2
  • 30
  • 25
  • Isn't this a bad example? I believe it's not really safe to use Super unless your whole hierarchy is "new style" classes and properly calling Super().init() – Jaykul May 23 '14 at 15:04
14

There's a super() in Python too. It's a bit wonky, because of Python's old- and new-style classes, but is quite commonly used e.g. in constructors:

class Foo(Bar):
    def __init__(self):
        super(Foo, self).__init__()
        self.baz = 5
Lawrence
  • 10,142
  • 5
  • 39
  • 51
9

If you don't know how many arguments you might get, and want to pass them all through to the child as well:

class Foo(bar)
    def baz(self, arg, *args, **kwargs):
        # ... Do your thing
        return super(Foo, self).baz(arg, *args, **kwargs)

(From: Python - Cleanest way to override __init__ where an optional kwarg must be used after the super() call?)

Community
  • 1
  • 1
Robin Winslow
  • 10,908
  • 8
  • 62
  • 91
9

I would recommend using CLASS.__bases__ something like this

class A:
   def __init__(self):
        print "I am Class %s"%self.__class__.__name__
        for parentClass in self.__class__.__bases__:
              print "   I am inherited from:",parentClass.__name__
              #parentClass.foo(self) <- call parents function with self as first param
class B(A):pass
class C(B):pass
a,b,c = A(),B(),C()
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • 2
    Bear in mind that, as you can tell from the volume of references to **super** here, that folks are really loath to use __bases__ unless you are doing something really deep. If you don't like **super**, look at **mro**. Taking the first entry in **mro** is safer than tracking which entry in __bases__ to use. Multiple inheritance in Python scans certain things backward and others forward, so letting the language unwind the process is safest. – Jon Jay Obermark Aug 31 '14 at 15:31
5

There is a super() in python also.

Example for how a super class method is called from a sub class method

class Dog(object):
    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self,x):
        self.moves.append('walk')
        self.moves.append('run')
        self.moves.append(x)
    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super().moves_setup("hello world")
        self.moves.append('fly')
dog = Superdog('Freddy')
print (dog.name)
dog.moves_setup()
print (dog.get_moves()) 

This example is similar to the one explained above.However there is one difference that super doesn't have any arguments passed to it.This above code is executable in python 3.4 version.

kkk
  • 1,850
  • 1
  • 25
  • 45
5

In this example cafec_param is a base class (parent class) and abc is a child class. abc calls the AWC method in the base class.

class cafec_param:

    def __init__(self,precip,pe,awc,nmonths):

        self.precip = precip
        self.pe = pe
        self.awc = awc
        self.nmonths = nmonths

    def AWC(self):

        if self.awc<254:
            Ss = self.awc
            Su = 0
            self.Ss=Ss
        else:
            Ss = 254; Su = self.awc-254
            self.Ss=Ss + Su   
        AWC = Ss + Su
        return self.Ss


    def test(self):
        return self.Ss
        #return self.Ss*4

class abc(cafec_param):
    def rr(self):
        return self.AWC()


ee=cafec_param('re',34,56,2)
dd=abc('re',34,56,2)
print(dd.rr())
print(ee.AWC())
print(ee.test())

Output

56

56

56
Georgy
  • 12,464
  • 7
  • 65
  • 73
Khan
  • 1,288
  • 12
  • 11
3

In Python 2, I didn't have a lot luck with super(). I used the answer from jimifiki on this SO thread how to refer to a parent method in python?. Then, I added my own little twist to it, which I think is an improvement in usability (Especially if you have long class names).

Define the base class in one module:

 # myA.py

class A():     
    def foo( self ):
        print "foo"

Then import the class into another modules as parent:

# myB.py

from myA import A as parent

class B( parent ):
    def foo( self ):
        parent.foo( self )   # calls 'A.foo()'
Community
  • 1
  • 1
BuvinJ
  • 10,221
  • 5
  • 83
  • 96
  • 2
    You have to use ````class A(object):```` instead of ````class A():```` Then super() will work – blndev Sep 17 '17 at 16:50
  • I'm not sure I follow. Do you mean in the definition of the class? Obviously, you have to indicate a class has a parent somehow in order to think you could to refer to a parent! Since, I posted this 9 months ago, I'm a bit fuzzy n the details, but I think I meant the examples from Arun Ghosh, lawrence, kkk, etc. are not applicable in Py 2.x. Instead, here's a method that works and an easy way to refer to the parent so it's a bit more clear what you're doing. (like using super) – BuvinJ Sep 18 '17 at 12:37
2
class department:
    campus_name="attock"
    def printer(self):
        print(self.campus_name)

class CS_dept(department):
    def overr_CS(self):
        department.printer(self)
        print("i am child class1")

c=CS_dept()
c.overr_CS()
maryam mehboob
  • 338
  • 5
  • 17
1

If you want to call the method of any class, you can simply call Class.method on any instance of the class. If your inheritance is relatively clean, this will work on instances of a child class too:

class Foo:
    def __init__(self, var):
        self.var = var
    
    def baz(self):
        return self.var

class Bar(Foo):
    pass

bar = Bar(1)
assert Foo.baz(bar) == 1
philosofool
  • 773
  • 4
  • 12
-2
class a(object):
    def my_hello(self):
        print "hello ravi"

class b(a):
    def my_hello(self):
    super(b,self).my_hello()
    print "hi"

obj = b()
obj.my_hello()
shim
  • 9,289
  • 12
  • 69
  • 108
  • 5
    Welcome to stackoverflow. This question has already been answered in details almost ten years ago now, the answer accepted and largely upvoted, and your answer doesn't add anything new. You may want to try and answer more recent (and preferably unanswered) questions instead. As a side note, there's a button in the editor to apply proper code formatting. – bruno desthuilliers Aug 31 '18 at 13:48
-26

This is a more abstract method:

super(self.__class__,self).baz(arg)
  • 15
    self.__class__ doesn't work right with super as self is always the instance and its __class__ is always the instance's class. This means if you use super(self.__class__.. in a class and that class is inherited from, it won't work anymore. – xitrium Aug 23 '11 at 21:34
  • 16
    Just to emphasize, DO NOT USE THIS CODE. It defeats the entire purpose of super(), which is to correctly traverse the MRO. – Eevee Feb 06 '12 at 21:31
  • 1
    http://stackoverflow.com/a/19257335/419348 said why not call `super(self.__class__, self).baz(arg)`. – AechoLiu Aug 21 '14 at 06:32