python深入之类继承资源的使用机制(重点)

关于常见的几种继承形态

(1)单继承:

 

(2)无重叠多继承:

 

(3)有重叠多继承

 

关于继承形态对应遵循的原则(重点)

(1)单继承遵循“从下往上”原则,即A-B-C-D

(2)无重叠多继承遵循“从下往上,单调向上”原则,即A-B-D-C-E

(3)有重叠多继承遵循“从下往上,重复可用”原则,即A-B-C-D

关于python类继承资源使用方案的演化(重中之重)

(1)python2.2之前

一.在python2.2之前只有经典类,即没有继承其他类的类,资源的使用遵循的是MRO(Method Resolution Oder)原则,即方法解析顺序,这个原则的核心是“深度优先,从左往右”

二.深度优先即沿着一条继承链尽可能往深处找,具体做法是首先把根节点压入栈(先进后出)中,从栈中弹出节点,再找到该节点所有的下一级节点,并从右往左压入栈中,重复上述操作知道结束

三.深度优先原则不适用于有重叠多继承形态,推算出的结果是A-B-D-C,与理论上的结果产生矛盾

(2)python2.2

一.python2.2中出现了新式类,即继承了其他类的类。经典类依然遵循MRO原则,而新式类在MRO原则的基础上进行了优化,增加了重复可用原则,即出现重复的类,则以最终那个类为准,这样解决了深度优先原则不适用于有重叠多继承形态的问题,即A-B-D-C-D,去掉中间的D,最终变成正确的A-B-C-D

二.上述优化的原则并不是“广度优先”原则,广度优先原则是:将深度优先原则中用到的栈,换成队列(先进先出),将根节点放入队列,然后取出,再寻找根节点的所有次级节点,并从左到右方法队列中,每取出一个,就找其此节点放入队列,直至结束。需要注意的是,广度优先原则不适用于无重叠多继承形态

三.python2.2新增查看资源使用顺序的方法,即inspect模块中的getmro(类)方法

四.改进后的MRO原则依然存在几个问题:1.无法检测出有问题的继承;2.可能会违背“局部优先”原则,举个例子:

 

这是一个错误的继承关系图,A继承了B,E也继承了B,而A又继承了E,这里前面A继承B就是多余的继承,因为A可以通过继承E来继承B,C,D的属性和方法。但是使用优化的MRO原则进行推算,不会报错,同时得到的结果是A-E-B-C-D,而从结果中可以看出,先E后B,这就违背了多继承中的“从左到右”原则

(3)python2.3-python2.7

一.这几个版本中同样有经典类和新式类共存,这里经典类依然遵循深度优先原则,而为新式类设计出了C3算法

下面给出使用C3算法推算的有重叠多继承形态的代码:

import inspect
class D(object):
    pass
# L(D(object)) = [D] + merge(L(object), [object])
#              = [D] + merge(([object] + merge(L(), [])), [object])
#              = [D] + merge([object], [object])
#              = [D, object]
class C(D):
    pass
# L(C(D)) = [C] + merge(L(D), [D])
#         = [C] + merge([D, object], [D])
#         = [C, D] + merge([object], [])
#         = [C, D, object]
class B(D):
    pass
# L(B(D)) = [B, D, object]
class A(B, C):
    pass
# L(A(B, C)) = [A] + merge(L(B), L(C), [B, C])
#            = [A] + merge([B, D, object], [C, D, object], [B, C])
#            = [A, B] + merge([D, object], [C, D, object], [C])
#            = [A, B, C] + merge([D, object], [D, object], [])
#            = [A, B, C, D, object]
print(inspect.getmro(A))

最终的结果是A-B-C-D-object

(4)python3

一.python3中只有新式类,这是为了避免深度优先原则在经典类中产生的问题(不适用于有重叠多继承形态)而设计的

二.python3中查看资源使用顺序的途径除了使用inspect模块中的getmro()方法外,还可以使用mro()方法和__mro__属性来查看

三.C3算法与拓扑算法:拓扑算法是1.找到入度(有几个子类,入度就是几)为0的节点;2。输出这个节点,并从图中删除该节点,以及这个节点的出边(连到父类的线);重复上述操作直至结束。C3算法与拓扑算法推算出的结果大多时候是相同的,但是在有些有问题的继承关系上,拓扑算法不会报错,如:

 

C3算法会报错,而拓扑算法的结果是A-E-B-C-D

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值