I wonder how is class C
being executed in this code flow When none of the flow calls it.
class A:
def fun1(self):
print("This is class A")
class B(A):
def fun2(self):
super().fun1()
print("This is class B")
class C(A):
def fun1(self):
super().fun1()
print("This is class C")
class D(B, C):
def fun1(self):
self.fun2()
print("This is class D")
obj = D()
obj.fun1()
"""
# Result of this code is
This is class A
This is class C
This is class B
This is class D
"""
The method resolution order used is a C3 linearization algorithm, and super
itself uses this MRO. The resolution for a type is obtained with the mro()
method, and cached in the __mro__
attribute:
>>> D.__mro__
(__main__.D, __main__.B, __main__.C, __main__.A, object)
>>> D.mro()
[__main__.D, __main__.B, __main__.C, __main__.A, object]
Since you call print after calling super, you'll see the reverse of this, ie A -> C -> B -> D .
I wonder how is class C being executed in this code flow when none of the flow calls it.
D.fun2
doesn't exist, so obj.fun2()
gets resolved (via the MRO) on B
instead:
>>> obj = D()
>>> obj.fun2
<bound method B.fun2 of <__main__.D object at 0x7fffe89a3cd0>>
Then in B.fun2
, the C.fun1
gets called here:
class B(A):
def fun2(self):
super().fun1() # <-- this resolves to C.fun1, not A.fun1!
print("This is class B")
That's because the MRO which is active here is that of the type(self)
, ie it's D's mro, not B's mro. Note that super()
does not always resolve on the parent class, it can be resolved on a sibling class like in your example. Python's implementation was more or less lifted from another programming language called Dylan , where super
was named next-method
, a less confusing name in my opinion.
This existing stackoverflow post does a good job of explaining things in a lot of detail. I encourage you to check it out.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.