简体   繁体   中英

What is the difference between calling a method from parent class using super() and using self?

class Car:
    def __init__(self, car_name, manufacturer, cost):
        self.__car_name=car_name
        self.__manufacturer=manufacturer
        self.__cost=cost

    def display_car_details(self):
        print(self.__car_name, self.__manufacturer, self.__cost)

class Super_Car(Car):
    def __init__(self, car_name, manufacturer, cost, 
                 top_speed, material_used, engine_type):
        super().__init__(car_name, manufacturer, cost)
        self.__top_speed=top_speed
        self.__material_used=material_used
        self.__engine_type=engine_type

    def display_super_car_details(self):
        self.display_car_details()  # this?
        super().display_car_details()  # or that?
        print(self.__top_speed, self.__material_used, 
              self.__engine_type)

Please tell me the difference between calling display_car_details() by using self.… and calling by super().… . The method which calls the above function is in Super_car class with name display_super_car_details() .

In your specific case, there is no difference. If the methods had the same name , you would not be calling the parent class using self.… , but your own method again, creating infinite recursion.

With super() , the call is always going to the method in the parent class in Method Resolution Order , thus preventing the infinite recursion. More details on super() itself can also be found in the official documentation .

Generally, you only need super() if you really need the inherited method, such as when re-implementing that exact method.

For example, running this code will lead to RecursionError , due to maximum recursion depth exceeded. The reason is that Bar.method1() calls itself over and over, because we are using self.… instead of super().… .

class Foo:
    def method1(self):
        print("I just want to be called")

class Bar(Foo):
    def method1(self):
        self.method1()  # oops

b = Bar()
b.method1()

This on the other hand has the intended effect:

class Foo:
    def method1(self):
        print("I just want to be called")

class Bar(Foo):
    def method1(self):
        super().method1()  # sweet

b = Bar()
b.method1()

Again, in your specific example it does not matter, because the other method ( display_car_details ) is only defined in the parent class , so it is unambiguous which method to call. If you had overridden display_car_details with something different, the use of super() and self would again yield different results:

class Bar(Foo):
   def method1(self):
       print("You are not supposed to call this")
   def method2(self):
       super().method1()
   def method3(self):
       self.method1()

Observe the difference in the interactive interpreter:

>>> b = Bar()
>>> b.method1()
You are not supposed to call this
>>> b.method2()
I just want to be called
>>> b.method3()
You are not supposed to call this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM