By SeanLabs


2015-07-05 15:45:38 8 Comments

I am working with some code that has 3 levels of class inheritance. From the lowest level derived class, what is the syntax for calling a method 2 levels up the hierarchy, e.g. a super.super call? The "middle" class does not implement the method I need to call.

5 comments

@LucianoDemuru 2019-02-23 08:22:36

Made and tested in python 3

class Vehicle:

    # Initializer / Instance Attributes
    def __init__(self, name, price):
        self.name = name
        self.price = price

    # instance's methods
    def description(self):
        print("\nThe car {} has a price of {} eur".format(self.name, self.price))
#Object Vehicle

m3 = Vehicle("BMW M3", 40000)

m3.description()

class Camper(Vehicle):

     def __init__(self,nome,prezzo,mq):
         super().__init__(nome,prezzo)
         self.mq=mq

         # instance's methods

     def description(self):
         super().description()
         print("It has a dimension of",format(self.mq)+" mq")

#Camper Object(A camper is also a Vehicle)
marcopolo=Camper("Mercede MarcoPolo",80000,15)

marcopolo.description()

Output:
The car BMW M3 has a price of 40000 eur
The car Mercede MarcoPolo has a price of 80000 eur
It has a dimension of 15 mq

@anand tripathi 2017-02-21 15:42:12

You can do this by following ways

class Grandparent(object):
    def my_method(self):
        print "Grandparent"

class Parent(Grandparent):
    def my_other_method(self):
        print "Parent"

class Child(Parent):
    def my_method(self):
        print "Inside Child"
        super(Child, self).my_method()

In this case Child will call base class my_method but base class my_method is not present there so it will call base class of parent class my_method in this way we can call my_method function of grandparent

Another Way

class Grandparent(object):
    def my_method(self):
        print "Grandparent"

class Parent(Grandparent):
    def my_other_method(self):
        print "Parent"

class Child(Parent):
    def my_method(self):
        print "Inside Child"
        super(Parent, self).my_method()

In this way we are directly calling function base class my_method function of the parent class

Another way but not pythonic way

class Grandparent(object):
    def my_method(self):
        print "Grandparent"

class Parent(Grandparent):
    def my_other_method(self):
        print "Parent"

class Child(Parent):
    def my_method(self):
        print "Inside Child"
        Grandparent.my_method()

In this way we are directly calling my_method function by specifying the class name.

@Martijn Pieters 2017-05-31 13:01:39

Never, ever, EVER use self.__class__ in super(). Not even to get at the bases. self.__class__ is not always the class on which you defined the method, it could be a subclass. If you add another two levels of inheritance, you now have an infinite loop.

@Tomasz 2018-01-18 09:00:52

This works for me:

class Grandparent(object):
    def my_method(self):
        print "Grandparent"

class Parent(Grandparent):
    def my_method(self):
        print "Parent"

class Child(Parent):
    def my_method(self):
        print "Hello Grandparent"
        super(Parent, self).my_method()

@nesdis 2018-02-08 03:08:17

This is probably the answer that must be marked as the right answer

@Tushar Vazirani 2019-04-02 09:38:09

This isn't the best answer because this solution wouldn't work for situations with higher order ancestors. The child class method is hard-coding the call to the Parent's super class. CrazyCasta's first answer, although bad practice, is the right answer to this question.

@IamnotBatman 2016-01-29 17:40:59

If you want two levels up, why not just do

class GrandParent(object):                                                       

    def act(self):                                                               
        print 'grandpa act'                                                      

class Parent(GrandParent):                                                       

    def act(self):                                                               
        print 'parent act'                                                       

class Child(Parent):                                                             

    def act(self):                                                               
        super(Child.__bases__[0], self).act()                                    
        print 'child act'                                                        


instance = Child()                                                               
instance.act()

# Prints out
# >>> grandpa act
# >>> child act      

You can add something defensive like checking if __bases__ is empty or looping over it if your middle classes have multiple inheritance. Nesting super doesn't work because the type of super isn't the parent type.

@Martijn Pieters 2017-05-31 13:02:05

Never, ever, EVER use self.__class__ in super(). Not even to get at the bases. self.__class__ is not always the class on which you defined the method, it could be a subclass. If you add another two levels of inheritance, you now have an infinite loop.

@CrazyCasta 2015-07-05 15:59:45

Well, this is one way of doing it:

class Grandparent(object):
    def my_method(self):
        print "Grandparent"

class Parent(Grandparent):
    def my_method(self):
        print "Parent"

class Child(Parent):
    def my_method(self):
        print "Hello Grandparent"
        Grandparent.my_method(self)

Maybe not what you want, but it's the best python has unless I'm mistaken. What you're asking sounds anti-pythonic and you'd have to explain why you're doing it for us to give you the happy python way of doing things.

Another example, maybe what you want (from your comments):

class Grandparent(object):
    def my_method(self):
        print "Grandparent"

class Parent(Grandparent):
    def some_other_method(self):
        print "Parent"

class Child(Parent):
    def my_method(self):
        print "Hello Grandparent"
        super(Child, self).my_method()

As you can see, Parent doesn't implement my_method but Child can still use super to get at the method that Parent "sees", i.e. Grandparent's my_method.

@Malik Brahimi 2015-07-05 16:02:43

I don't think you can do nested super calls anyway because the type would be super.

@SeanLabs 2015-07-05 16:05:09

In my case the Parent class does not implement my_method, and I don't want to add it just for the sake of getting the child call to work.

@Anand S Kumar 2015-07-05 16:06:17

You don't need to, middle class inherits methods from parent classes, so doing super().method() would work.

@information_interchange 2017-08-28 05:00:59

Is the 1st method or 2nd method preferred? Are there any cases where they won't have the same behaviour?

@CrazyCasta 2017-08-28 18:42:18

@information_interchange Well, generally it's a pretty bad idea to use the first method. I only gave it because I thought it was what was being asked for. The second method is by far preferred. You should not be trying to skip through a higher class if you can help it.

@Hamed_gibago 2017-10-17 11:48:23

@CrazyCasta One question. Is it usable in interactive IDLE python shell? I think calling super method just works when we save files and running them.

@CrazyCasta 2017-10-18 05:19:22

@Hamed_gibago If you're asking if you define the classes in the interactive shell whether it will work or not, yes it will work. AFAIK IDLE python shell is just a more GUIish version of the command line shell and it works fine in the command line shell. Run my code, followed by "a = Child()" and "a.my_method()".

@Hamed_gibago 2017-10-18 06:41:31

@CrazyCasta I didn't find AFAIK IDLE shell, but thank you for make me aware to search for other shell. ;)

@CrazyCasta 2017-10-18 22:07:10

@Hamed_gibago No, I'm saying As Far As I Know (AFAIK) IDLE Python shell... I don't have IDLE Python to test with, but I'd be willing to bet if it's not working it's either a version issue (2.7 vs 3.x) or some confusion.

@Hamed_gibago 2017-10-19 09:22:58

@CrazyCasta thanks man, sorry for AFAIK ;)

@CrazyCasta 2017-10-22 01:16:52

@Hamed_gibago Yeah, np. Btw, I checked and it doesn't work in python 3, so if you're using python 3 that would be why (need to put parenthesis around the print arguments).

Related Questions

Sponsored Content

7 Answered Questions

[SOLVED] Understanding Python super() with __init__() methods

26 Answered Questions

[SOLVED] Why not inherit from List<T>?

27 Answered Questions

[SOLVED] What is the Python equivalent of static variables inside a function?

  • 2008-11-10 23:33:36
  • andrewdotnich
  • 307946 View
  • 570 Score
  • 27 Answer
  • Tags:   python

15 Answered Questions

[SOLVED] Call a parent class's method from child class?

22 Answered Questions

[SOLVED] Creating a singleton in Python

18 Answered Questions

[SOLVED] Convert bytes to a string

16 Answered Questions

[SOLVED] String formatting: % vs. .format

6 Answered Questions

[SOLVED] Python class inherits object

10 Answered Questions

[SOLVED] Iterating over dictionaries using 'for' loops

7 Answered Questions

[SOLVED] super() raises "TypeError: must be type, not classobj" for new-style class

Sponsored Content