Guido本人在他的博客文章“方法解决顺序”(包括之前的两次尝试)中对此进行了合理的详细介绍。
在您的示例中,将调用 。Python在类的父级中查找每个属性,因为它们从左到右列出。在这种情况下,我们正在寻找.因此,如果您定义Third()
First.__init__
__init__
class Third(First, Second):
...
Python 将从 查看 开始,如果没有该属性,则它将查看 。First
First
Second
当继承开始交叉路径(例如,如果继承自 )时,这种情况变得更加复杂。阅读上面的链接以获取更多详细信息,但是,简而言之,Python将尝试保持每个类在继承列表中出现的顺序,从子类本身开始。First
Second
因此,例如,如果您有:
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"
的 MRO 应该是 还是 ?没有明显的期望,Python会引发一个错误:Third
[First, Second]
[Second, First]
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution order (MRO) for bases Second, First
为什么上面的例子缺少调用?这些示例的要点是展示 MRO 是如何构造的。它们不是为了打印或其他任何东西。当然,你可以——当然,应该尝试这个例子,添加调用,看看会发生什么,并更深入地了解Python的继承模型。但我在这里的目标是保持简单,并展示MRO是如何构建的。正如我所解释的那样,它是构建的:super()
"first\nsecond\third"
super()
>>> Fourth.__mro__
(<class '__main__.Fourth'>,
<class '__main__.Second'>, <class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)