python MRO:C3算法

在 python 2.2 以后,python 实现了一个新的MRO算法:C3算法,用于方法解析顺序 。 python

1、什么是方法解析顺序  算法

方法解析顺序 :多重继承时,用于在子类中调用父类方法时肯定调用哪一个父类的方法 。 编程

多重继承代码示例:


#!/usr/bin/python 
#-*- coding:utf8 -*-

class A(object):
    def echo(self):
        print "class_A"

class B(A):
    pass
    #def echo(self):
    #    print "class_B"

class C(A):
    def echo(self):
        print "class_C"


class D(B,C):
    pass 
print D.__mro__  //python使用__mro__ 来存储线性化计算的结果。


ubuntu@yee:/tmp$ python mro.py 
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
能够看到顺序为: D --> B --> C --> A --> object 


当子类D调用echo方法时:  ubuntu


D().echo()
python 先搜索 D 本地类,再搜索B,有则返回,无则继续搜索C ,以此类推。


2、C3算法的原理 spa

 上面示例代码中所用到的正是C3算法,算法的表达式为: code

L[D(B,C)] 
= D + merge(L[B],L[C],[B,C])

以上表达式也等同于: 
==> 
L[D(B,C)] = D + merge(mro(B,object),mro(C,object),[B,C]) ==> L[D(B,C)] = D + merge( [B,object], [C, object],[B,C])  [] : 列表表达式
merge: C3算法的核心
《python高级编程》中是这样写的: 
取第一个列表的头,也就是L[B,object] ,若是这个头不在任何表的尾部,那么将它加到Class D的线性化中,而且从合并中的列表里删除 ;不然查找下一个列表的头,若是是个好的表头则取出它。 须要注意的是: 表头指是第一个元素 ,尾部是指除表头以外的其它全部元素 。如[A,B,C,D,E,F],A是表头,[B,C,D,E,F]是尾部。


方式解析: 继承

L(D(B,C)) =  D + merge( [B,object] ,[C,object] , [B,C] )   class

                  #列表[B,object]的表头是B,没有出如今其它表([C,object] 、[B,C] )的尾部  原理

               =  [D, B] + merge( [object], [C,object] , [C] )    object

                  #列表[C,object]的表头是C,没有出如今其它表([object] 、[C] )的尾部 ,注意 [C] 这个列表只有表头,没有尾部

               =  [D, B,C] + merge( [object] , [object] )

               =  [D, B,C,object]                                 

经过以上的运算,能够得出跟 D().__mro__ 同样的结果 。

相关文章
相关标签/搜索