Guido 本人在他的博客文章中详细介绍了这一点方法解析顺序 http://python-history.blogspot.com/2010/06/method-resolution-order.html(包括之前的两次尝试)。
在你的例子中,Third()
将会通知First.__init__
。 Python 在类的父类中查找从左到右列出的每个属性。在这种情况下,我们正在寻找__init__
。所以,如果你定义
class Third(First, Second):
...
Python 首先会查看First
, 而如果First
没有该属性,那么它会查看Second
.
当继承开始交叉路径时,这种情况变得更加复杂(例如,如果First
继承自Second
)。阅读上面的链接了解更多详细信息,但是,简而言之,Python 将尝试维护每个类在继承列表中出现的顺序,从子类本身开始。
因此,举例来说,如果您有:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First):
def __init__(self):
print "third"
class Fourth(Second, Third):
def __init__(self):
super(Fourth, self).__init__()
print "that's it"
MRO 将是[Fourth, Second, Third, First].
顺便说一句:如果 Python 找不到一致的方法解析顺序,它会引发异常,而不是回退到可能让用户感到惊讶的行为。
不明确的 MRO 示例:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First, Second):
def __init__(self):
print "third"
Should Third
的 MRO 是[First, Second]
or [Second, First]
?没有明显的期望,Python 将引发错误:
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution order (MRO) for bases Second, First
为什么上面的例子缺少super()
打电话?这些示例的目的是展示 MRO 是如何构建的。他们是not打算打印"first\nsecond\third"
管他呢。当然,您可以并且应该尝试一下这个例子,添加super()
调用,看看会发生什么,并更深入地了解 Python 的继承模型。但我的目标是保持简单并展示 MRO 的构建方式。它是按照我解释的方式构建的:
>>> Fourth.__mro__
(<class '__main__.Fourth'>,
<class '__main__.Second'>, <class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)