What is the difference between calling a method from parent class using super() and using self?
<pre><code>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)
</code></pre>

<p>Please tell me the difference between calling <code>display_car_details()</code> by using <code>self.â¦</code> and calling by <code>super().â¦</code>. The method which calls the above function is in <code>Super_car</code> class with name <code>display_super_car_details()</code>.</p>

<p>In your specific case, there is no difference. If the methods had the <em>same name</em>, you would not be calling the parent class using <code>self.â¦</code>, but your own method again, creating infinite recursion.</p>

<p>With <code>super()</code>, the call is always going to the method in the parent class in <a href="https://rhettinger.wordpress.com/2011/05/26/super-considered-super/" rel="nofollow">Method Resolution Order</a>, thus preventing the infinite recursion. More details on <code>super()</code> itself can also be found in the <a href="https://docs.python.org/3/library/functions.html#super" rel="nofollow">official documentation</a>.</p>

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

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

<pre><code>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()
</code></pre>

<p>This on the other hand has the intended effect:</p>

<pre><code>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()
</code></pre>

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

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

<p>Observe the difference in the interactive interpreter:</p>

<pre><code>&gt;&gt;&gt; b = Bar()
&gt;&gt;&gt; b.method1()
You are not supposed to call this
&gt;&gt;&gt; b.method2()
I just want to be called
&gt;&gt;&gt; b.method3()
You are not supposed to call this
</code></pre>

python python-3.x oop