6

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?

11
  • 1
    did you try A.m(self) instead of using super? Commented Sep 22, 2015 at 11:23
  • @MathiasEttinger no I didn't, but now I tried it and it works perfectly. Thanks. You can post it as answer, because it solved my problem Commented Sep 22, 2015 at 11:26
  • for that to work, A.m() must be a class method Commented Sep 22, 2015 at 11:26
  • 1
    No, it’s an unbound method and you are providing the self parameter manualy Commented Sep 22, 2015 at 11:30
  • 1
    @Andrius Seems that you got confused with super(). super(SomeClass, someobject) will lookup attributes in the class that follows SomeClass in the MRO of someobject. In your case super(A, self).m() refers to object.m(self), which clearly does not exist. Commented Sep 22, 2015 at 11:52

2 Answers 2

8

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.

Sign up to request clarification or add additional context in comments.

Comments

5

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'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.