Python方法解析顺序

Ish*_*ori 4 python oop inheritance multiple-inheritance method-resolution-order

有人可以解释给定代码的输出以及在这种情况下 python 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(C, B):
    def go(self):
        super(D, self).go()
        print("go D go!")


d = D()
d.go()

Run Code Online (Sandbox Code Playgroud)

输出:

go A go!
go B go!
go C go!
go D go!
Run Code Online (Sandbox Code Playgroud)

按照从左到右和深度,我会说它应该是:

go A go!
go C go!
go D go!
Run Code Online (Sandbox Code Playgroud)

但似乎它不像我想的那样工作。

Ray*_*ger 7

一个班级的 MRO 基于它的父母的 MRO:

>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
Run Code Online (Sandbox Code Playgroud)

三个规则是:

  1. 孩子走在父母之前:
  • A < 对象
  • B < A
  • C < A
  • D < C
  • D < B
  1. 父母按照基地的顺序:
  • C < B
  1. 父 mros 被合并,保留它们的顺序。
  • 合并B < A < objectC < A < object

在 Python 2 的早期,搜索规则曾经是深度优先左或右,但随着对 C3 线性化算法的研究而改变。

有关在实际代码中利用此算法的方法,请参阅Super Considered Super博客文章。

  • D的mro是DCBAObj。这意味着这些类是按该顺序调用的。B 被调用是因为它在列表中,没有其他原因。 (3认同)