发布时间:2018-04-06 20:36:03编辑:admin阅读(5135)
先来看一个经典类
class A: def __init__(self): print('A') class B(A): def __init__(self): print('B') class C(A): def __init__(self): print('C') class D(B,C): pass obj = D()
继承顺序如下图:
B如果有构造函数,就不会继承C的构造函数
找到第一个构造函数,就停下来,不再寻找了。
构造函数只会执行一次,先从本身找,找不到,就去上层寻找,顺序如下:
D->B->C->A
执行上面的代码,输出:B
为什么会输出B呢?往下看
将B的构造函数注释掉
class A: def __init__(self): print('A') class B(A): pass # def __init__(self): # print('B') class C(A): def __init__(self): print('C') class D(B,C): pass obj = D()
执行输出:C
将C的构造函数注释掉
class A: def __init__(self): print('A') class B(A): pass # def __init__(self): # print('B') class C(A): pass # def __init__(self): # print('C') class D(B,C): pass obj = D()
执行输出:A
这是一个正常的寻找顺序
那么问题来了
B虽然没有构造函数,但是它继承了A,它应该从A中继续寻找构造函数才对啊
为什么去找C呢?
因为D找B的时候,B发现没有,虽然B可以从A中继承,A是更高层的,先不找它。
BC是属于同一层的(继承B,C),既然B没有,那么去找C了。
这种查询策略,叫做广度优先
先从横向策略(D->B->C->A) 查找,如果找不到了,再从上层找。
查找有很多策略
上面说到B没有,不应该就这么结束了,直接去找C了。应该从A中查找,A如果没有,再找C,顺序如下:
D->B->A->C
这种查询策略,叫做深度优先
这里没有所谓的对错,是2种查询策略,也叫继承策略
在不同的场景下,会选择不同的查询策略
从上面的例子可以看出,是属于广度优先
从python3开始,都是广度优先
使用python2执行如下代码:
class A(): def __init__(self): print('A') class B(A): pass # def __init__(self): # print('B') class C(A): def __init__(self): print('C') class D(B,C): pass obj = D()
执行输出:A
可以看出,python2使用的是 深度优先
上面的代码是经典类写法
下面看一下新式类的写法
只是将A()改为A(object)
class A(object): def __init__(self): print('A') class B(A): pass # def __init__(self): # print('B') class C(A): def __init__(self): print('C') class D(B,C): pass obj = D()
使用python3和python2执行
结果都是C
总结:
python2 经典类是按深度优先来继承的,新式类是按广度优先来继承的
python3 经典类和新式类都是统一按广度优先来继承的
在python2中,继承效率来讲,深度优先不如广度优先
所以在python3中,统一改成广度优先
上一篇: python 多层装饰器分析
下一篇: python 面向对象之继承实例讲解
47744
46234
37109
34626
29228
25885
24744
19862
19415
17907
5715°
6314°
5834°
5887°
6983°
5829°
5844°
6360°
6315°
7672°