python - Python MRO - 在多重继承中使用 super
问题描述
我有这段代码,其中使用了超级继承和多重继承。上课的结果是:
go A go!
go C go!
go B go!
go D go!
虽然我期望:
go A go!
go B go!
go D go!
根据我的理解:D因为MRO调用B类,因为go是在B中实现的。B类调用其父A的super。A被执行,没关系。然后我希望 B 继续执行,所以这意味着 B 被执行,最后 D 被执行。但这当然是不正确的。为什么它进入C,因为go方法的定义在B中找到,然后它不应该再在C中搜索。这就是MRO的工作原理。它在头等舱中找到,不应再搜索。完全糊涂了:(
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!")
a = A()
b = B()
c = C()
d = D()
d.go()
解决方案
Raymond Hettinger(核心 python 开发人员)在PyCon 上提供了一段出色的视频。
主要的收获是超级不叫你的父母,它叫你后代的祖先。因此,无论何时调用super
,它都会返回到您实际调用该方法的实例,并在 MRO 中查找下一个类型(即使具有多重继承也是保证顺序,为什么class D(B,C)
与 不同class D(C, B)
)。
在您的情况下,D 的 MRO 是 (D,B,C,A)。当D.go
调用 super 时,它调用B.go
. 当调用 super 时,它仍在使用 D 的 MRO,因此它移动到下一种类型,在您的情况下,C 又调用 A。最终结果是您的打印语句在 D 的 MRO 中执行反转。
如果您无法观看 youtube,这里还有一个 RH 的博客,其中也涵盖了相同的主题。
推荐阅读
- excel - 如何在excel中找到给定职位要求的行的总和
- python - Spark SQL:按滚动 7 天时间段对行进行分组
- electron - 透明mac窗口渲染双文字
- c++ - C++ 组合枚举映射
- asp.net-mvc - 在 1 个视图中插入 2 个表数据
- c++ - 在 Windows 上构建 CMake Release 比 Debug 需要几个小时
- python-3.x - 使用 Pytorch 进行文本处理(Pytorch Text)
- amazon-web-services - 如何使用 IP 填充主机文件然后调用 ansible 剧本
- r - R: 如何将 map(read_html) 用于多个 URL?
- kubernetes - 即使添加了 pod-disruption-budget,Google Kubernetes 集群也不会自动缩减