super()
如何处理多重继承?例如,给定:
class First(object):
def __init__(self):
print "first"
class Second(object):
def __init__(self):
print "second"
class Third(First, Second):
def __init__(self):
super(Third, self).__init__()
print "that's it"
Third
的哪个父方法 super().__init__
指的是什么?我可以选择运行哪些吗?
我知道它与方法解析顺序 ( MRO ) 有关。
原文由 Callisto 发布,翻译遵循 CC BY-SA 4.0 许可协议
Guido 本人在他的博客文章 Method Resolution Order (包括之前的两次尝试)中详细介绍了这一点。
在您的示例中,
Third()
将调用First.__init__
。 Python 查找类的父类中的每个属性,因为它们是从左到右列出的。在这种情况下,我们正在寻找__init__
。所以,如果你定义Python 将首先查看
First
,如果First
没有属性,那么它将查看Second
当继承开始跨越路径时,这种情况变得更加复杂(例如,如果
First
继承自Second
)。阅读上面的链接了解更多详细信息,但是,简而言之,Python 将尝试维护每个类在继承列表中出现的顺序,从子类本身开始。因此,例如,如果您有:
MRO 将是
[Fourth, Second, Third, First].
顺便说一句:如果 Python 找不到一致的方法解析顺序,它会引发异常,而不是退回到可能让用户感到惊讶的行为。
模棱两可的 MRO 示例:
Third
的 MRO 应该是[First, Second]
还是[Second, First]
?没有明显的期望,Python 将引发错误:为什么上面的示例缺少
super()
调用?这些示例的目的是展示 MRO 是如何构建的。它们 无意 打印"first\nsecond\third"
或其他内容。您可以——当然应该尝试这个示例,添加super()
调用,看看会发生什么,并更深入地了解 Python 的继承模型。但我的目标是保持简单并展示 MRO 是如何构建的。它是按照我的解释建造的: