Python Call Parent Method Multiple Inheritance
10,477
Solution 1
You can use __bases__
like this
class D(A, B, C):
def foo(self):
print("foo from D")
for cls in D.__bases__:
cls().foo("D")
With this change, the output will be
foo from D
foo from A, call from D
foo from B, call from D
foo from C, call from D
Solution 2
Add super()
call's in other classes as well except C
. Since D's MRO is
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <type 'object'>)
You don't need super call in C
.
Code:
class A(object):
def foo(self, call_from):
print "foo from A, call from %s" % call_from
super(A,self).foo('A')
class B(object):
def foo(self, call_from):
print "foo from B, call from %s" % call_from
super(B, self).foo('B')
class C(object):
def foo(self, call_from):
print "foo from C, call from %s" % call_from
class D(A, B, C):
def foo(self):
print "foo from D"
super(D, self).foo("D")
d = D()
d.foo()
Output:
foo from D
foo from A, call from D
foo from B, call from A
foo from C, call from B
Related videos on Youtube

Author by
Edwin Lunando
Updated on June 09, 2022Comments
-
Edwin Lunando 7 months
So, i have a situation like this.
class A(object): def foo(self, call_from): print "foo from A, call from %s" % call_from class B(object): def foo(self, call_from): print "foo from B, call from %s" % call_from class C(object): def foo(self, call_from): print "foo from C, call from %s" % call_from class D(A, B, C): def foo(self): print "foo from D" super(D, self).foo("D") d = D() d.foo()
The result of the code is
foo from D foo from A, call from D
I want to call all parent method, in this case, foo method, from
D
class without using super at the parent class likeA
. I just want to call the super from theD
class. TheA
,B
, andC
class is just like mixin class and I want to call all foo method fromD
. How can i achieve this? -
Edwin Lunando about 9 yearsIn case you do not understand my description, I want to call all
foo
method without calling super at the parent class likeA
orB
orC
. -
mgilson about 9 years@EdwinLunando -- I believe that's just not how it goes. In order for super to work properly, all the classes need to use it. see the section on mixing super methods with non super methods.
-
Ashwini Chaudhary about 9 years@EdwinLunando Then iterate over
__mro__
, or__bases__
and call each class explicitly, but then you can't usesuper
inD
. -
mgilson about 9 yearsThis is a little sketchy ... What if you now have two classes which both inherit from D and then another class which inherits from both of those? Now
foo
will callA.foo
twice. -
mgilson about 9 yearsOr what happens if
B.foo
doesn't exist? And finally, I think it should becls.foo(self)
, notcls().foo()
-
thefourtheye about 9 years@mgilson Then, we have to use
mro
? And those are not class methods, right? So, I had to create objects to call them. -
mgilson about 9 yearsThey're not class methods, but you can call the method from the class if you explicitly pass
self
as the first argument (andself
is of the correct type). -
thefourtheye about 9 yearsIn this case, we don't have a problem with
self
, but in his actual code, he might mutateself
and that would create problems. So, it would be better to call it this way, I believe -
Edwin Lunando about 9 yearsThis is what I need! Thank you. :D. I changed the
D__bases__
intoself.__class__.__bases__
and it work greatly. -
interjay over 8 yearsThis solution is wrong because now calling
A().foo()
orB().foo()
will raise an exception. You can now only use these classes from a derived class which also derives fromC
(or a similar class), and the order becomes important as well (C
must be last). To make this work correctly, you'd need all classes to be derived from a base class that implementsfoo
.