Reputation: 21108
Let say I have 3 classes: A, B and C. A is a base class for B and B is for C. Hierarchy is kept normally here, but for one method it should be different. For C class it should act like it was inherited from A.
For example like this:
class A(object):
def m(self):
print 'a'
class B(A):
def m(self):
super(B, self).m()
print 'b'
class C(B):
def m(self):
super(A, self).m()
print 'c'
So basically it should work like this:
a = A()
a.m()
a
b = B()
b.m()
a
b
c = C()
c.m()
a
c
But it is not going to work for C class, because I get this error:
AttributeError: 'super' object has no attribute 'm'
To solve this for C class I could inherit from class A, but I want to inherit everything from B and for that specific method m
call super for base class A. I mean that method is one exception. Or should I call it somehow differently for class C in order to work?
How can I do that?
Upvotes: 6
Views: 2045
Reputation: 77902
There are in fact two ways to solve this: you can shortcut the call to super()
and totally bypass the mro as in Mathias Ettinger's answer, or you can just issue the correct call to super()
:
class C(B):
def m(self):
super(B, self).m()
print 'c'
Remember that super()
expects as first argument the class from which it should start looking up the mro. It's usually the class in which the call is made, but you can pass another class upper in the mro if you want.
Upvotes: 8
Reputation: 4186
Using the super
call, python will inspect the MRO of your class to determine which class to use when calling the function you want.
Since you want to short-circuit this behaviour, you can explicitly state the class you want to use the method from with:
class C(B):
def m(self):
A.m(self)
print 'c'
Upvotes: 5