python-mro
C3算法
- 当一个类多继承时,写在前面的类的优先级高于后面的,其子类也要保证这个特性。
class A:
def f(self):
print('A')
class B:
def f(self):
print('B')
class C(B, A):
pass
class D(C):
pass
C().f() # B
D().f() # B
- 单调性,任何一个类其使用的方法必须来自于其直接父类
- 如果两个类不具有直接的继承关系,那么找到两个类的最小公共子类,这个最小公共子类的多继承顺序靠前的分支上的类具有高优先级。
大神古地名觉的总结
https://www.modb.pro/db/441279
当沿着一条继承链寻找类时,默认沿着 该继承链一直寻找下去,如果发现某个类在另外一条继承链中也存在,那么当前的继承链的搜索就会结束,然后再最开始出现分歧的地方转向下一条继承链。
1)因为是 A 的 MRO,所以查找时,第一个类就是 A;
2)然后 A 继承 B 和 C,由于是两条路,因此我们说 A 这里就是一个分歧点。但由于 B 在前,所以接下来是 B,而现在 MRO 的顺序就是 A B;
3)但是 B 这里也出现了分歧点,不过不用管,因为我们说会沿着继承链不断往下搜索,现在 MRO 的顺序是A B D;
4)然后从 D 开始继续寻找,这里注意了,按理说会找到 G 的。但是 G 不止被一个类继承,也就是说沿着当前的继承链查找 G 时,发现 G 还出现在了其它的继承链当中。怎么办?显然要回到最初的分歧点,转向下一条继承链的搜索;
5)最初的分歧点是 A,那么该去找 C 了, 现在 MRO 的顺序就是 A B D C;
6)注意 C 这里也出现了分歧点,而 A 的两条分支已经结束了,所以现在 C 就是最初的分歧点了。而 C 继承自 E 和 F,显然要搜索 E,那么此时 MRO 的顺序就是 A B D C E;
7)然后从 E 开始搜索,显然要搜索 G,此时 MRO 顺序变成 A B D C E G;
8)从 G 要搜索 I,此时 MRO 的顺序是 A B D C E G I;
9)从 I 开始搜索谁呢?由于 J 出现在了其它的继承链中,那么要回到最初的分歧点,也就是 C。那么下面显然要找 F,此时 MRO 的顺序是 A B D C E G I F;
10)F 只继承了 H, 那么肯定要找 H, 此时 MRO 的顺序是 A B D C E G I F H;
11)H 显然只能找 J 了,因此最终 A 的 MRO 的顺序就是 A B D C E G I F H J object;