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.)