Reputation: 10176
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?
Upvotes: 834
Views: 964338
Reputation: 42692
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()
Upvotes: 171
Reputation: 973
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
Upvotes: 1
Reputation: 400562
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)
Upvotes: 1061
Reputation: 1498
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
Upvotes: 5
Reputation: 388
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()
Upvotes: 2
Reputation: 7764
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)
Upvotes: 89
Reputation: 27
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()
Upvotes: -2
Reputation: 973
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.
Upvotes: 81
Reputation: 11086
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()'
Upvotes: 3
Reputation: 11502
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)
Upvotes: 9
Reputation: 1920
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.
Upvotes: 5
Reputation: 882481
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!
Upvotes: 92
Reputation: 4695
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
Upvotes: 32
Reputation: 114048
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()
Upvotes: 9
Reputation: 1
This is a more abstract method:
super(self.__class__,self).baz(arg)
Upvotes: -26
Reputation: 10760
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
Upvotes: 14