为大家所知的Python中类的继承方式是多继承,但是在Python2.x中类的是有经典类和新式类两种(Python3.x中都是新式类),所以也导致了两中类型在继承时会有一些差别。
新式类跟经典类的差别主要是以下几点:
新式类:继承于object的类都是新式类。
经典类:不是继承object的类都是经典类
- 新式类对象可以直接通过 _ _ class _ _属性获取自身类型:type
注释:type是一个函数来获取类的类型,而_ _ class _ _是类的属性的方式来获取类的类型,不同方法获取相同的东西。
- 继承搜索的顺序发生了改变,经典类多继承时属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧(即深度优先搜索);新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动
截止到python2.1,只存在旧式类。旧式类中,类名和type是无关的:如果x是一个旧式类,那么x.class定义了x的类名,但是type(x)总是返回<type 'instance'>。这反映了所有的旧式类的实例是通过一个单一的叫做instance的内建类型来实现的,这是它和新式类不同的地方。
新式类是在python2.2为了统一类和实例引入的。一个新式类只能由用户自定义。如果x是一个新式类的实例,那么type(x)和x._ _ class _ _ 是一样的结果(尽管这不能得到保证,因为新式类的实例的_ _ class_ _方法是允许被用户覆盖的)。
Python
'测试环境python2.7'
'搜索顺序是(深度优先): D B A C'
'这里是深度优先'
'这是经典类'
>>> class A: attr = 1
...
>>> class B(A): pass
...
>>> class C(A): attr = 2
...
>>> class D(B,C): pass
...
>>> x = D()
>>> x.attr
1
'测试环境python2.7'
'搜索顺序是(广度优先): D B C A'
'这里是深度优先'
'这是新式类'
>>> class A(object): attr = 1
...
>>> class B(A): pass
...
>>> class C(A): attr = 2
...
>>> class D(B,C): pass
...
>>> x = D()
>>> x.attr
2
- 如果是经典类MRO为DFS(深度优先搜索(子节点顺序:从左到右))。
- 如果是新式类MRO为BFS(广度优先搜索(子节点顺序:从左到右))。
关于深度算法和广度算法的区别,很简单
先来一张图这有利于理解
到了这里如果还是不懂的话那就再来一个更简单的
二话不说先上图
大家是否记得js时第一节课的document树,这里是一种特殊的树——二叉树。(对照上面的正常继承[菱形继承则是另一种'图'])
A可以看作object B是继承A B的孩子有D E
现在我们要访问整个树叫做遍历方式,这里有两种方式(当然也不止这两种那些不是今天的关键)深度优先算法和广度优先算法(层次优先)
深度优先
1.先访问根节点
2.访问左孩子
3.访问右孩子
4.重复以上动作直到所有节点访问完毕
第一步 访问 A
|—第二步 访问 B
|—第三步访问D
|—第四步访问E
|—第五步访问C
|—第三步访问F
|—第四步访问G行
A->B->D->E->C->F->G
广度优先(层次优先)
宽度优先搜索或横向优先搜索,是从根结点开始沿着树的宽度搜索遍历,
上面二叉树的遍历顺序为:ABCDEFG.
这里就可以很好的解释第二张图,如果对棱型继承还是不理解可以在下方留言我会用数据结构的另一种方式去体现广度优先。
大家如果还有什么地方不懂的可以在评论区提问,我都会一一解答。