Python多继承的特殊例子(C3算法)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python多继承的特殊例子(C3算法)相关的知识,希望对你有一定的参考价值。
之前看课程的时候一直说python3新式类中多继承顺序解析的时候,用的是广度优先算法,再之后就看到了下面这个例子
多重继承的执行顺序,请解答以下输出结果是什么?并解释。
class A(object):
def __init__(self):
print('A')
super(A, self).__init__()
class B(object):
def __init__(self):
print('B')
super(B, self).__init__()
class C(A):
def __init__(self):
print('C')
super(C, self).__init__()
class D(A):
def __init__(self):
print('D')
super(D, self).__init__()
class E(B, C):
def __init__(self):
print('E')
super(E, self).__init__()
class F(C, B, D):
def __init__(self):
print('F')
super(F, self).__init__()
class G(D, B):
def __init__(self):
print('G')
super(G, self).__init__()
if __name__ == '__main__':
g = G()
f = F()
继承关系如图
如果按照讲的广度优先,那么E的搜索顺序,就是EBCA;F的搜索顺序就是FCBDA;G的顺序就是GDBA
其实想到这里的时候就能感觉到有问题,因为从上到下看B是和A是一层的,而从下到上看,可能B就会和C、D划到一层
所以感觉应该问题没有这么简单,所以打出来搜索顺序看一下:
print(G.__mro__)
# (<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(F.__mro__)
# (<class '__main__.F'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)
print(E.__mro__)
# (<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
可以看到G的搜索顺序,是GDAB,这是为什么呢,搜索到D的时候向深度走了一层,才跳到了B,和广度优先的认知不太一样;而如果按照这种方法走的话,F的顺序又为啥不是先C后A再B这样呢
明显广度优先是有问题的
那么到底是按照什么算法寻找的呢
可以看下这篇文章:https://hanjianwei.com/2013/07/25/python-mro/
用的是C3算法,其实也比较好理解
在merge的时候,每次都是将列表头取出,然后查看这表头是否在其他列表的尾部,如果在,那么就跳过,取下一个列表的头部重复这个判断;如果不在,加入最终的顺序列表
用这个算法计算上面那个例子结果如下:
主要关注F的顺序,在判断A的时候,因为A也出现在了后面列表的尾部,所以跳过了A,先搜索了B和D
L[A] := [A,O]
L[B] := [B,O]
L[C] := [C,A,O]
L[D] := [D,A,O]
L[E] := [E] + merge(L[B],L[C],[B],[C])
= [E] + merge([B,O],[C,A,O],[B],[C])
= [E,B] + merge([O],[C,A,O],[C])
= [E,B,C] + merge([O],[A,O])
= [E,B,C,A] + merge([O],[O])
= [E,B,C,A,O]
L[F] := [F] + merge(L[C],L[B],L[D],[C],[B],[D])
= [F] + merge([C,A,O],[B,O],[D,A,O],[C],[B],[D])
= [F,C] + merge([A,O],[B,O],[D,A,O],[B],[D])
= [F,C,B] + merge([A,O],[O],[D,A,O],[D])
= [F,C,B,D] + merge([A,O],[O],[A,O])
= [F,C,B,D,A] + merge([O],[O],[O])
= [F,C,B,D,A,O]
L[G] := [G] + merge(L[D],L[B],[D],[B])
= [G] + merge([D,A,O],[B,O],[D],[B])
= [G,D] + merge([A,O],[B,O],[B])
= [G,D,A] + merge([O],[B,O],[B])
= [G,D,A,B] + merge([O],[O],[O])
= [G,D,A,B,O]
以上是关于Python多继承的特殊例子(C3算法)的主要内容,如果未能解决你的问题,请参考以下文章