gpt4 book ai didi

python - 为什么 Python 的 C3 MRO 依赖于一个通用的基类?

转载 作者:太空宇宙 更新时间:2023-11-04 03:05:55 25 4
gpt4 key购买 nike

当我读到 Python 的 C3 方法解析顺序时,我经常听到它被简化为“子类在父类之前,子类的顺序是受尊重的”。然而,这似乎只有在所有子类都继承自同一祖先的情况下才成立。

例如

class X():
def FOO(self):
return 11

class A(X):
def doIt(self):
return super().FOO()
def FOO(self):
return 42

class B(X):
def doIt(self):
return super().FOO()
def FOO(self):
return 52

class KID(A,B):
pass

这里KID的MRO是: child ,A,B,X

但是,如果我将 B 改为:

class B(object):

KID的MRO变为: child ,A,X,B

看起来我们在搜索完所有 KID 的父类之前就搜索了 A 的父类(super class)。

所以它现在看起来比“ child 优先,广度优先”更直观一点,而不是“ child 优先,广度优先,如果有共同的祖先,否则深度优先”。

如果一个类停止使用共同的祖先,MRO 就会发生变化(即使整个层次结构除了那个链接之外是相同的),并且您开始调用更深层次的祖先方法而不是那个类。

最佳答案

Python 3 中的所有类都有一个共同的基类,object .您可以省略 class 中的类定义,但除非您已经间接继承自 object,否则它就在那里. (在 Python 2 中,您必须显式继承自 object 才能使用 super(),因为这是一种新式类功能)。

您更改了 B 的基类来自 Xobject ,但是X 继承自object . MRO 更改以考虑到这一点。 C3 规则的相同简化( child 在 parent 之前,子类的顺序受到尊重)在这里仍然适用。 Bobject 之前, 和 X 一样, 和 AB仍然以相同的顺序列出。然而,X应该在 B 之前,因为两者都继承自 object和子类 A(X)B 之前在KID .

请注意,没有任何地方说 C3 是广度优先。如果有的话,那就是深度优先。参见 The Python 2.3 Method Resolution Order有关该算法及其如何应用于 Python 的深入描述,但任何类的线性化都是合并基类线性化和基类本身的结果:

L[KID] = KID + merge(L[A], L[B], (A, B))

哪里L[..]是该类的 C3 线性化(他们的 MRO)。

所以 A 的线性化在 B 之前合并时,使 C3 深入而不是广度地查看层次结构。合并从最左边的列表开始,并获取未出现在其他列表尾部的任何元素(因此除了第一个元素之外的所有元素),然后获取下一个,依此类推。

在您的第一个示例中,L[A]L[B]几乎相同(它们的 MRO 都以 (X, object) 结尾,只有第一个元素不同),所以合并很简单;你合并(A, X, object)(B, X, object) ,合并这些只会给你 A从第一个列表,然后是整个第二个列表,以 (KID, A, B, X, object) 结尾在添加 KID 之后:

L[KID] = KID + merge((A, X, object), (B, X, object), (A, B))
# ^ ^^^^^^
# \ & \ both removed as they appear in the next list
= KID + (A,) + (B, X, object)
= (KID, A, B, X, object)

在你的第二个例子中,L[A] 不变,但是L[B]现在是(B, object) (删除 X ),所以合并更喜欢 X之前 B作为(A, X, object)合并时先出现 X没有出现在第二个列表中。因此

L[KID] = KID + merge((A, X, object), (B, object), (A, B))
# ^^^^^^
# \removed as it appears in the next list
= KID + (A, X) + (B, object)
= (KID, A, X, B, object)

关于python - 为什么 Python 的 C3 MRO 依赖于一个通用的基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39488324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com