多继承在针对派生类中的同名函数时,python 需要对其进行线性化(C3 Linearization),将继承图关系线性化。通过线性化,再依次查找类方法,直至找到该方法为止。线性化算法是python多继承的核心部分。线性化过程中,必须满足两个性质:
单调性
如果C从C'直接继承属性P(如图1),(C != C'),C'所有的父类(包含C')均在线性化中都是C的子列表。这样的话,C的线性化列表不用遍历C的所有继承体系,直接通过C的直接继承父类线性化列表获得(通过归并父类列表获得)。
一致性
直接父类的顺序通过用户来声明,父类线性化的顺序为从左到右。在进行线性化归并过程中,一致性主要保证类的局部优先级顺序,它定义了两个变量:
1) precC:类C的局部顺序
2) prec:局部顺序的并集
类C1,C2,C1 < precC C2 ===> C1 < prec C2,prec 为无环关系图。
通过上面的两个定义,引申出最终边的关系图。扩展关系 a
假设类的继承关系图为:
通过计算扩展关系
5
2
4
4
这样最终的关系图为:
线性化关系为:
- L(7) = {'object'}
- L(4) = {'4','7'}
- L(5) = {'5','7'}
- L(6) = {'6','7'}
- L(2) = {'2','4','5','7','object'}
- L(3) = {'3','4','6','7','object'}
- L(1) = {'1','2','3','4','5','6','7','object'}
python 代码如下:- #! /usr/bin/env python
- #
- # multi inheritance view
- # /------ 7-------\
- # / | \
- # 4 - 5 6
- # \\ / /
- # 2-/\--- 3------/
- # \ /
- # 0,1
- #
- #
- class C7(object):
- def test(self):
- print 'test in C7'
- class C4(C7):
- def test(self):
- print 'test in C4'
- class C5(C7):
- def test(self):
- print 'test in C5'
- class C6(C7):
- def test(self):
- print 'test in C6'
- class C2(C4,C5):
- def test(self):
- print 'test in C2'
- class C3(C4,C6):
- pass
- class C1(C2,C3):
- pass
- class C0(C2,C3):
- def test(self):
- print 'test in C0'
- super(C3,self).test()
- if __name__ == "__main__":
-
- c1 = C1()
- c1.test()
- c0 = C0()
- c0.test()
- print C7.__mro__
- print C6.__mro__
- print C5.__mro__
- print C4.__mro__
- print C3.__mro__
- print C2.__mro__
- print C1.__mro__
- print C0.__mro__
输出结果为:- test in C2
- test in C0
- test in C4
- (<class '__main__.C7'>, <type 'object'>)
- (<class '__main__.C6'>, <class '__main__.C7'>, <type 'object'>)
- (<class '__main__.C5'>, <class '__main__.C7'>, <type 'object'>)
- (<class '__main__.C4'>, <class '__main__.C7'>, <type 'object'>)
- (<class '__main__.C3'>, <class '__main__.C4'>, <class '__main__.C6'>, <class '__main__.C7'>, <type 'object'>)
- (<class '__main__.C2'>, <class '__main__.C4'>, <class '__main__.C5'>, <class '__main__.C7'>, <type 'object'>)
- (<class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.C3'>, <class '__main__.C4'>, <class '__main__.C5'>, <class '__main__.C6'>, <class '__main__.C7'>, <type 'object'>)
- (<class '__main__.C0'>, <class '__main__.C2'>, <class '__main__.C3'>, <class '__main__.C4'>, <class '__main__.C5'>, <class '__main__.C6'>, <class '__main__.C7'>, <type 'object'>)