0
class A(object):
    def test(self):
        print("test of A called")


class B(A):
    def test(self):
        print("test of B called")
        super(B, self).test()


class C(A):
    def test(self):
        print("test of C called")
        super(C, self).test()


class D(B, C):
    def test2(self):
        print("test of D called")

obj = D()
obj.test()

The output of the above code is

test of B called
test of C called
test of A called

but I don't understand how the control flow here is working. super with parameter is confusing me.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • Please, indent your code – alec_djinn Jul 26 '23 at 17:57
  • `super()` simply allows you to call methods from the inherited class. Here it is explained very well https://www.geeksforgeeks.org/python-super/ – alec_djinn Jul 26 '23 at 18:00
  • The parameters do not change anything about the control flow here. It's as if `super()` without parameters was used everywhere. – mkrieger1 Jul 26 '23 at 18:03
  • Does this answer your question? [Understanding Python super() with \_\_init\_\_() methods](https://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods) – Brian61354270 Jul 26 '23 at 18:05
  • 1
    Does this answer your question? [What does 'super' do in Python? - difference between super().\_\_init\_\_() and explicit superclass \_\_init\_\_()](https://stackoverflow.com/questions/222877/what-does-super-do-in-python-difference-between-super-init-and-expl) – mkrieger1 Jul 26 '23 at 18:05
  • In Python 2, arguments to `super` were required. Python 3 added the ability to infer the arguments that are virtually always intended. Here, those arguments are just being passed explicitly. – chepner Jul 26 '23 at 18:16
  • arguments are required if you modify the behaviour of the class _dynamically_ – cards Jul 26 '23 at 19:33

1 Answers1

0

Super() function is used to call a method from a parent class in a method resolution order (MRO). When a class is derived from multiple parent classes (like in the case of class D), the MRO defines the order in which Python searches for the method when it encounters a method call.

Let's break down the control flow step by step to understand the output:

  1. You create an object obj of class D.
  2. When you call obj.test(), Python starts looking for the test() method in the class hierarchy of D according to the MRO.
  3. Since D inherits from both B and C, Python follows the MRO, which, in this case, is D -> B -> C -> A.
  4. Python finds the test() method in class B first. So, it executes the test() method of class B.
  5. Inside the test() method of class B, you have super(B, self).test(). Here, super(B, self) means "call the method of the parent class of B (i.e., A)". So, Python executes the test() method of class A.

Now let's examine the order of the print statements:

  1. "test of B called" is printed when the test() method of class B is executed.
  2. "test of C called" is printed from super(B, self).test(), which calls the test() method of class C.
  3. "test of A called" is printed from super(C, self).test(), which calls the test() method of class A.

So, the final output is:

test of B called
test of C called
test of A called

It's essential to understand the method resolution order and how super() works, especially in cases where a class inherits from multiple parent classes, as the order of execution can be critical in achieving the desired behavior.

Ömer Sezer
  • 197
  • 5
  • Is it like adding the calls in a stack, like first it will search for test method in class D, but not finding it in class D, according to MRO it will search in B and finds the test and adds it in the stack s = [B] then moves to class C adds it s = [B, C], now calling the test of class B so stack = [C] now through B we get test method of A so s = [C, A] and then it call test of both classess. Am I right? – yashberchha Jul 27 '23 at 08:17