1

Suppose class A is inherited from B and B is inherited from C.

class C():
    def my_method(self):
        pass

class B(C):
    def my_method(self):
        pass

class A(B):
    def my_method(self):
        # Call my_method from B
        super(A, self).my_method()
        # How can I call my_method from C here ?

Question: How can I call my_method from C ?

quamrana
  • 37,849
  • 12
  • 53
  • 71
s ahmad ef
  • 57
  • 6
  • You mean the parent class of `SomeClass`? – Dschoni Feb 21 '17 at 14:34
  • Sounds like an [XY-problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). In generally you shouldn't need to access specific ancestors, just let `super` figure out whom to access, that's the whole point about ["MRO" (method resolution order)](https://www.python.org/download/releases/2.3/mro/). – MSeifert Feb 21 '17 at 14:35
  • Note there is only one object created by `A()`. This object is an instance of all its super classes but there are no individual objcets created for the parent classes. – MB-F Feb 21 '17 at 14:42
  • "How can I call my_method from C ?" — *Which* `my_method`, and what's the type of the object you're calling it on? – jwodder Feb 21 '17 at 15:05

3 Answers3

1

You can call C's my_method() method simply by calling the "unbound" method directly, with self passed as an argument. For example:

class C(object):
    def my_method(self):
        print('C.my_method')

class B(C):
    def my_method(self):
        print('B.my_method')

class A(B):
    def my_method(self):
        print('A.my_method')
        super(A, self).my_method()  # calls B.my_method(self)
        C.my_method(self)           # calls C.my_method(self)

a = A()
a.my_method()

When run, that will print the following (note the (object) is required for super() to work on Python 2.x):

A.my_method
B.my_method
C.my_method

However, as others have pointed out, this may not be the best way to achieve what you want. Can you give a concrete example of what you're trying to achieve in context?

Ben Hoyt
  • 10,694
  • 5
  • 60
  • 84
  • Actually I want to override my_method in class A, in other words, I'm going to add some functionality to my_method of class C, not class B. – s ahmad ef Feb 21 '17 at 15:45
0

You can access the full ancestry of an object using its __mro__ attribute:

In [3]: KeyError.__mro__
Out[3]: (KeyError, LookupError, StandardError, Exception, BaseException, object)
scytale
  • 12,346
  • 3
  • 32
  • 46
0

First of all if you want to use super function then you have to use base class as object like this

class c(object):
    pass

Because super function support in only new style programming of python only.

Now coming to how to access function of base class of base class. In your case how to call my_method function of class C from A.

You can do this in two ways statically and dynamically.

Dynamically

class C(object):
    def my_method(self):
        print "in function c"

class B(C):
    def my_method(self):
        print "in function b"

class A(B):
    def my_method(self):
        # Call my_method from B
        super(A, self).my_method()
        # This is how you can call my_method from C here ?
        super((self.__class__.__bases__)[0], self).my_method()
obj_a = A()
obj_a.my_method()

Here (self.__class__.__bases__) will return base classes of A in tuple type thats why i took the 0th index. So it return the class B so having B class as a argument in super it will return my_method function of base class of b class.

Statically

class C(object):
    def my_method(self):
        print "in function c"

class B(C):
    def my_method(self):
        print "in function b"

class A(B):
    def my_method(self):
        # Call my_method from B
        super(A, self).my_method()
        # This is how you can call my_method from C here ?
obj_a = A()
super(A,obj_a).my_method() # calls function of class B
super(B,obj_a).my_method() # calls function of class A
Anand Tripathi
  • 14,556
  • 1
  • 47
  • 52