几种标准原则的方案演化
Python2.2之前
仅仅存在经典类
MRO原则:深度优先(从左往右)
问题:"有重叠的多继承"中, 违背"重写可用原则"
Python2.2
产生了新式类
MRO原则
经典类
深度优先(从左到右)
新式类
在深度优先(从左到右)的算法基础之上, 优化了一部分
如果产生重复元素, 会保留最后一个
并且, 更尊重基类出现的先后顺序
注意:
并不是"广度优先算法"
问题
无法检测出有问题的继承
有可能还会违背"局部优先"的原则
子类继承多个父类
如果子类没有, 应按照父类从左到右的顺序, 优先查找
例如
图示
按照"上述算法", 计算结果为
A -> C -> B -> D -> object
问题是: A继承 (B, C)
A中没有, 应该优先选择左侧的B呀
Python2.3-2.7
新式类经典类并存
MRO原则
经典类
深度优先(从左到右)
新式类
C3算法
Python3.x之后
MRO原则
新式类
C3算法
概念补充
MRO
MRO(Method Resolution Order)
方法解析顺序
深度优先
沿着一个继承链, 尽可能的往深了去找
具体算法步骤
1. 把根节点压入栈中
2. 每次从栈中弹出一个元素,搜索所有在它下一级的元素
把这些元素压入栈中
发现已经被处理, 则略过
3. 重复第2个步骤到结束为止
广度优先
沿着继承链, 尽可能往宽了去找
具体算法步骤
把根节点放到队列的末尾
每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾
发现已经被处理, 则略过
重复上面步骤
C3算法
真正步骤
两个公式
L(object) = [object]
L(子类(父类1, 父类2)) = [子类] + merge(L(父类1), L(父类2) , [父类1, 父类2])
注意
+ 代表合并列表
merge算法
1. 第一个列表的第一个元素
是后续列表的第一个元素
或者
后续列表中没有再次出现
则将这个元素合并到最终的解析列表中
并从当前操作的所有列表中删除
2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则
3. 如果最终无法把所有元素归并到解析列表, 则报错
类似拓扑排序, 但并不是! 切记
具体算法步骤
选择一个入度为0的顶点并输出之;
从网中删除此顶点及所有出边。