为什么 MRO 在下面的代码中 python 是反向的?
why MRO is reverse in python in below code?
class Z():
def func():
print ("I'm in Z")
class A(Z):
def func():
print ("I'm in A")
class B(Z):
def func():
print ("I'm in B")
class C(A,B):
pass
#def func():
# print ("I'm in C")
ob1 = C
print ("Calling function func ")
ob1.func()
输出为:
Calling function func
I'm in A
但是根据How does Python's super() work with multiple inheritance?
顺序应该是 "depth-first left-to-right traversal" + "removing duplicates expect for the last"
如 /visionscaper(用户:889617)所述,
为什么会有这种差异?
在谈到遍历时,它首先搜索深度,从左到右,直到找到为止。它调用它找到的第一个。在你的情况下:
- 它在
C
中搜索 func
- 没有找到。向左下。
- 它在
A
中搜索 func
- 找到了。完毕。打印 I'm in A
.
如果 A
没有覆盖 func
,这很重要。在这种情况下:
- 它在
C
中搜索 func
- 没有找到。向左下。
- 它在
A
中搜索 func
- 没有找到。往下,不对。
- 它在
Z
中搜索 func
- 在那里找到它。打印 I'm in Z
.
继承层次结构的深度优先从左到右遍历 C
会得到:[C, A, Z, B, Z]
。由于 Python 不允许重复,第一个 Z
被删除,你最终得到 [C, A, B, Z]
。因此,当您调用 C.func()
时,您会从 A
获得实现。 A.func
中没有 super
个调用,所以该行到此结束。
您可以通过调用其 mro
方法获得任何 class 的完整 MRO:
>>> C.mro()
[__main__.C, __main__.A, __main__.B, __main__.Z, object]
在the answer I think you were referring to中,每个__init__
方法使用super
调用MRO中的下一个方法。但是由于他们每个人都在打印自己的消息之前进行了 super
调用,所以打印行的顺序最终与调用函数的顺序相反。你可以让它以与MRO 通过将 print
行与超级调用交换,以便 print
调用首先发生。
class Z():
def func():
print ("I'm in Z")
class A(Z):
def func():
print ("I'm in A")
class B(Z):
def func():
print ("I'm in B")
class C(A,B):
pass
#def func():
# print ("I'm in C")
ob1 = C
print ("Calling function func ")
ob1.func()
输出为:
Calling function func
I'm in A
但是根据How does Python's super() work with multiple inheritance?
顺序应该是 "depth-first left-to-right traversal" + "removing duplicates expect for the last"
如 /visionscaper(用户:889617)所述,
为什么会有这种差异?
在谈到遍历时,它首先搜索深度,从左到右,直到找到为止。它调用它找到的第一个。在你的情况下:
- 它在
C
中搜索func
- 没有找到。向左下。 - 它在
A
中搜索func
- 找到了。完毕。打印I'm in A
.
如果 A
没有覆盖 func
,这很重要。在这种情况下:
- 它在
C
中搜索func
- 没有找到。向左下。 - 它在
A
中搜索func
- 没有找到。往下,不对。 - 它在
Z
中搜索func
- 在那里找到它。打印I'm in Z
.
继承层次结构的深度优先从左到右遍历 C
会得到:[C, A, Z, B, Z]
。由于 Python 不允许重复,第一个 Z
被删除,你最终得到 [C, A, B, Z]
。因此,当您调用 C.func()
时,您会从 A
获得实现。 A.func
中没有 super
个调用,所以该行到此结束。
您可以通过调用其 mro
方法获得任何 class 的完整 MRO:
>>> C.mro()
[__main__.C, __main__.A, __main__.B, __main__.Z, object]
在the answer I think you were referring to中,每个__init__
方法使用super
调用MRO中的下一个方法。但是由于他们每个人都在打印自己的消息之前进行了 super
调用,所以打印行的顺序最终与调用函数的顺序相反。你可以让它以与MRO 通过将 print
行与超级调用交换,以便 print
调用首先发生。