Home > Software design >  Python - Demystifying the use of super() to call grandparent method
Python - Demystifying the use of super() to call grandparent method

Time:02-25

I can't seem to fully understand how super() really works when it comes to calling methods of a grandparent class. Suppose for instance we have the following code

class A():
    def __init__(self):
        print("initializing A")
    def method(self):
        print("method A")

class B(A):
    def __init__(self):
        print("initializing B")
    def method(self):
        print("method B")

class C(B):
    def __init__(self):
        print("initializing C")
    def method(self):
        super(B, self).method()

c = C()
c.method()

this will output

initializing C
method A

What I don't get is why the syntax (meaning super(Parent, self).method()) is like that, and more importantly what's going on under the hood. The Python official documentation (here) says

class super([type[, object-or-type]]) - Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The object-or-type determines the method resolution order to be searched. The search starts from the class right after the type.

Why does the type passed to super([type[, object-or-type]]) have to be the parent class B and not the grandparent class A? And how does passing self (in this case the instance of class C) help in determining the method resolution order to be searched?

CodePudding user response:

The resolution order of C is [C, B, A, object]. When you use super, you are looking for the next class that provides the requested method. Inside C.method, super() and super(C, self) would be equivalent: look for the first definition of method in a class after C. When you pass B as the first argument, you are asking for the first definition of method in a class following B instead.

(The second argument, if not self, would be used to select an entirely different MRO, rather than just a different starting location for the search within the appropriate MRO.)

Use cases for other arguments to super are rare enough that it was worth adding special logic to the language itself to allow super() to be used in place explicit arguments. (They aren't just default function arguments, because the "default" values depend on the context in which super is called.)

  • Related