为什么在下面的代码中,MRO在python中是反向的?
输出为:为什么在下面的代码中,MRO在python中是反向的?,python,method-resolution-order,Python,Method Resolution Order,输出为: 调用函数func 我有麻烦了 但是根据 顺序应为“深度优先左向右遍历”+“删除重复项,最后一次除外” 如/visionscaper(用户:889617)所述 为什么会有这种差异?当谈到遍历时,它首先从左到右搜索深度,直到找到为止。它调用它找到的第一个。就你而言: 它在C中搜索func,但没有找到它。向左走 它在A中搜索func——找到它。完成。打印我在一个中 重要的是A没有覆盖func。在这种情况下: 它在C中搜索func,但没有找到它。向左走 它在A中搜索func,但没有找到它。下
调用函数func
我有麻烦了
但是根据
顺序应为“深度优先左向右遍历”+“删除重复项,最后一次除外”
如/visionscaper(用户:889617)所述
为什么会有这种差异?当谈到遍历时,它首先从左到右搜索深度,直到找到为止。它调用它找到的第一个。就你而言:
C
中搜索func
,但没有找到它。向左走A
中搜索func
——找到它。完成。打印我在一个中
A
没有覆盖func
。在这种情况下:
C
中搜索func
,但没有找到它。向左走A
中搜索func
,但没有找到它。下降了,不对Z
中搜索func
——在那里找到它。打印我在Z
继承层次结构的深度优先从左到右遍历
C
将给出:[C,A,Z,B,Z]
。因为Python不允许重复,所以第一个Z
被删除,最后得到[C,A,B,Z]
。因此,当调用C.func()
时,可以从A
获得实现。A.func
中没有super
调用,因此这是该行的结尾
通过调用任何类的MRO
方法,可以获取该类的完整MRO:
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()
在中,每个
\uuuu init\uuuu
方法通过使用super
调用MRO中的下一个方法。但是,由于它们在打印自己的消息之前都进行了super
调用,因此打印行的顺序最终与调用函数的顺序相反。您可以通过将print
行与super调用交换,使print
调用首先发生,从而使其与MRO的工作顺序相同。它的工作顺序完全是从左到右的深度优先。A是B的左边,作为C的父级。什么让你感到困惑?从C开始,深度优先从左到右遍历的下一个基类是C:A的最左边的基类。你期望什么?这里的查找顺序是A,Z,B(从B层次结构中删除A,Z作为重复项)物理学家:你的命令是错误的<代码>B必须出现在MRO中的Z
之前。也可以完成:直接跳到B,跳过A,Z作为重复项。检查实例字典。引发属性错误。第二种方案完全错误。如果A
没有实现func
,那么将调用B
的版本。C
的MRO为C、A、B、Z
Z
在任何MRO中都不会出现在B
之前,因为它是B
的父项。啊,是的,我明白了,你是对的。这就是我没有测试我写的东西所得到的。嗨,Blckknght,谢谢你消除了我的疑虑。实际上,当我在上面的例子中使用超级功能时,我感到困惑。你提到的线索是正确的,“我想你指的答案”也感谢其他人,他们试图消除我的疑虑。
>>> C.mro()
[__main__.C, __main__.A, __main__.B, __main__.Z, object]