ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

关于Python类的多继承中的MOR继承顺序问题

2019-02-11 19:47:29  阅读:678  来源: 互联网

标签:merge 继承 MOR 列表 A1 Python mro class


刚刚学到类的多继承这个环节,当子类继承多个父类时,调用的父类中的方法具体是哪一个我们无从得知,为此,在Python中有函数__mro__来表示方法解析顺序。

当前Python3.x的类多重继承算法用的是C3

MRO序列:

MRO是一个有序列表L,在类被创建时就计算出来。
通用计算公式为:mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )其中Child继承自Base1, Base2)如果类B继承类A:

这时类B的mro序列为:

mro( B ) = mro( B(A) )
= [B] + merge( mro(A) + [A] )
= [B] + merge( [A] + [A] )
= [B,A]

 

如果继承至多个基类:class B(A1, A2, A3 …)
这时B的mro序列为:

mro(B) = mro( B(A1, A2, A3 …) )
= [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] )
= ...

 

计算得到的结果为列表,列表中第一个元素为自身,如上述示例[A1,A2,A3],merge操作是C3算法的核心,了解了merge操作的原理,就了解了C3算法。

merge操作:

 

假如计算merge( [E,O], [C,E,F,O], [C] )

取出第一个列表[E,O]的表头E,进行判断:
各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
取出第二个列表[C,E,F,O]的表头C,进行判断:
C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除
merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
  ...

假设有如下的继承关系

计算mro(A)的方式为:

mro(A) = mro( A(B,C) )

原式= [A] + merge( mro(B),mro(C),[B,C] )

  mro(B) = mro( B(D,E) )
         = [B] + merge( mro(D), mro(E), [D,E] )  # 多继承
         = [B] + merge( [D,O] , [E,O] , [D,E] )  # 单继承mro(D(O))=[D,O]
         = [B,D] + merge( [O] , [E,O]  ,  [E] )  # 拿出并删除D
         = [B,D,E] + merge([O] ,  [O])
         = [B,D,E,O]

  mro(C) = mro( C(E,F) )
         = [C] + merge( mro(E), mro(F), [E,F] )
         = [C] + merge( [E,O] , [F,O] , [E,F] )
         = [C,E] + merge( [O] , [F,O]  ,  [F] )  # 跳过O,拿出并删除
         = [C,E,F] + merge([O] ,  [O])
         = [C,E,F,O]

原式= [A] + merge( [B,D,E,O], [C,E,F,O], [B,C])
    = [A,B] + merge( [D,E,O], [C,E,F,O],   [C])
    = [A,B,D] + merge( [E,O], [C,E,F,O],   [C])  # 跳过E
    = [A,B,D,C] + merge([E,O],  [E,F,O])
    = [A,B,D,C,E] + merge([O],    [F,O])  # 跳过O #注意O即为所有类的基类object
    = [A,B,D,C,E,F] + merge([O],    [O])
    = [A,B,D,C,E,F,O]

 根据上图的继承关系:

可以得到A的mro序列为:[A,B,D,C,E,F,O]

这里备注一下新式类和旧式类的区别:

Python2.X中有新式类和旧式类之分:

在Python2.X中,新式类需要特别定义为如下形式:

class Tencent(object):

 旧式类:

class Tencent()
#或者
class Tencednt:   #两种定义方式均为旧式类。

而在Python3.X中,所有类无论以哪种方式定义,均为形式类。

class Tencent():  #新式类
class Tencent:     #新式类
class Tencent(object):  #还是新式类

在Python2.X中mro使用的算法是深度优先原则。

 深度优先即从左往右依次先向上搜索,然后再按从左至右的顺序搜索。

在Python3.X中mro使用的算法是广度优先原则。

广度优先即先满足从左至右搜索的原则,然后在向上搜索。

标签:merge,继承,MOR,列表,A1,Python,mro,class
来源: https://www.cnblogs.com/LegendsNeverDie/p/10360560.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有