Reputation: 386
So we have a code snippet below. I don't understand why it behave this way. Why does super(B, self).go()
resolves to the go
method of the C
class?
class A(object):
def go(self):
print("go A go!")
class B(A):
def go(self):
super(B, self).go()
print("go B go!")
class C(A):
def go(self):
super(C, self).go()
print("go C go!")
class D(B, C):
def go(self):
super(D, self).go()
print("go D go!")
d = D()
d.go()
# go A go!
# go C go!
# go B go!
# go D go!
Upvotes: 0
Views: 95
Reputation: 531315
Despite its name, super
does not necessarily refer to a superclass. super(B, self)
refers to the class in self
's MRO that follows B
.
You can see the MRO for D with
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
This means that from d.go
, super(D, self)
refers to B
. When B.go
is called as a result, super(B, self)
refers to C
, not A
. This is because self
is still an instance of D
, so it is D.__mro__
that dictates what gets called next, not the static superclass of B
.
The most important thing to remember about super
is that inside Foo.go
, you do not know what class super(Foo, self)
will refer to, because you do not know if self
is an instance of Foo
or a descendent of Foo
.
Upvotes: 5