zoukankan      html  css  js  c++  java
  • 多重继承方法或属性调用顺序(MRO)

    参考摘选自这篇文章http://hanjianwei.com/2013/07/25/python-mro/ 

    python2.3以后采用c3方法来确定方法解析顺序

     我们把类 C 的线性化(MRO)记为 L[C] = [C1, C2,…,CN]。其中 C1 称为 L[C] 的头,其余元素 [C2,…,CN] 称为尾。如果一个类 C 继承自基类 B1、B2、……、BN,那么我们可以根据以下两步计算出 L[C]:

    1. L[object] = [object]
    2. L[C(B1…BN)] = [C] + merge(L[B1]…L[BN], [B1]…[BN])

    这里的关键在于 merge,其输入是一组列表,按照如下方式输出一个列表:

    1. 检查第一个列表的头元素(如 L[B1] 的头),记作 H
    2. 若 H 未出现在其它列表的尾部,则将其输出,并将其从所有列表中删除,然后回到步骤1;否则,取出下一个列表的头部记作 H,继续该步骤。
    3. 重复上述步骤,直至列表为空或者不能再找出可以输出的元素。如果是前一种情况,则算法结束;如果是后一种情况,说明无法构建继承关系,Python 会抛出异常。

    例1:

    L[object] = [object]
    L[D] = [D, object]
    L[E] = [E, object]
    L[F] = [F, object]
    L[B] = [B, D, E, object]
    L[C] = [C, D, F, object]
    L[A] = [A] + merge(L[B], L[C], [B], [C])
         = [A] + merge([B, D, E, object], [C, D, F, object], [B], [C])
         = [A, B] + merge([D, E, object], [C, D, F, object], [C])
         = [A, B, C] + merge([D, E, object], [D, F, object])
         = [A, B, C, D] + merge([E, object], [F, object])
         = [A, B, C, D, E] + merge([object], [F, object])
         = [A, B, C, D, E, F] + merge([object], [object])
         = [A, B, C, D, E, F, object]




    例2:
    class A(object):
        def go(self):
            print "go A go!"
        def stop(self):
            print "stop A stop!"
        def pause(self):
            raise Exception("Not Implemented")
    
    class B(A):
        def go(self):
            super(B, self).go()
            print "go B go!"
    
    class C(A):
        def go(self):
            super(C, self).go()
            print "go C go!"
        def stop(self):
            super(C, self).stop()
            print "stop C stop!"
    
    class D(B,C):
        def go(self):
            super(D, self).go()
            print "go D go!"
        def stop(self):
            super(D, self).stop()
            print "stop D stop!"
        def pause(self):
            print "wait D wait!"

    d=D()
    d.go()
    D的__mro__为D,B,C,A,object
    super的类型参数决定了在mro列表中的搜索起始位置,总是范围该参数后续类型的成员。(摘选自雨痕的python学习笔记)
    super(D,self).go()返回D后面的成员即B,B的go()又返回C,C的go()返回A,所以打印结果为
    go A go!
    go C go!
    go B go!
    go D go!


    class A(object):
        def go(self):
            print "go A go!"
        def stop(self):
            print "stop A stop!"
        def pause(self):
            raise Exception("Not Implemented")
    
    class B(A):
        def go(self):
            super(B, self).go()
            print "go B go!"
    
    class C(A):
        def go(self):
            super(C, self).go()
            print "go C go!"
        def stop(self):
            super(C, self).stop()
            print "stop C stop!"
    
    class D(B,C):
        def go(self):
            super(D, self).go()
            print "go D go!"
        def stop(self):
            super(D, self).stop()
            print "stop D stop!"
        def pause(self):
            print "wait D wait!"
  • 相关阅读:
    Java虚拟机(第二版) 学习笔记之Class类文件的结构
    JVM之深入浅出之垃圾收集算法
    Java虚拟机(第二版) 学习笔记之OutOfMemoryError
    Java虚拟机(第二版) 学习笔记
    平滑加权轮询负载均衡(轮询)算法
    java AQS(AbstractQueuedSynchronizer)同步器详解
    mybatis Interceptor拦截器代码详解
    aspectj编程简介
    Java并发编程阅读笔记-Java监视器模式示例
    我们该怎么结合日志做优化
  • 原文地址:https://www.cnblogs.com/songbird/p/7282724.html
Copyright © 2011-2022 走看看