前言
本群的作业,没有指定Python方向,而在于提升群内成员的语言功底,以便大家在Python的其他方向走的更远。
本群欢迎任何程度的Python学习者
Python程序设计 群号:651707058
先学会如何使用super函数
先看一个多继承的例子
先有A B C三个类,然后D同时继承了A B C
class A(object):
def __init__(self, x=0):
print('A',x)
self._x = x
class B(object):
def __init__(self, y=0):
print('B',y)
self._y = y
class C(object):
def __init__(self, z=0):
print('C',z)
self._z = z
class D(A,B,C):
def __init__(self,x,y,z):
print('D')
super(D,self).__init__(x)
super(A,self).__init__(y)
super(B,self).__init__(z)
print(D.__mro__)
obj_d = D('x','y','z')
'输出:'
'''
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)
D
A x
B y
C z
'''
多重继承的继承顺序实际上使用的MRO算法来排序,可以输出mro查看继承顺序,例如上面代码的继承顺序为上面的代码输出结果
所以根据mro算法的继承顺序:
super(D,self).init(x) 就是去初始化D的上一个类,也就是去初始化A
super(A,self).init(y) 就是去初始化A的上一个类,也就是去初始化B
super(B,self).init(z) 就是去初始化B的上一个类,也就是去初始化C
记住,super的顺序,并不是一个接一个地去初始化其父类,也就是super并不是去初始化其父类这种逻辑
执行三条super,D类的三个爸爸就初始化完了,成功完成了三个爸爸的愿望
看完上面的,你应该就已经学会了如果多继承,或者已经知道继承顺序是MRO算法得出来的
为什么要用MRO算法来获得继承顺序
MRO:Method Resolution Order,即方法解析顺序,是python中用于处理二义性问题的算法
先一个例子:
class D:
pass
class B(D):
pass
class E:
pass
class C(E):
pass
class A(B,C):
pass
'''
普通的搜索算法有: DFS深度优先算法 BFS广度优先算法
DFS: A->B->D->C->E (符合子类查到不到,再去父类查找)
BFS: A->B->C->D->E (不符合子类查到不到,再去父类查找,C不是B的父类)
现在看来DFS符合继承规则
'''
class D:
pass
class B(D):
pass
class C(D):
pass
class A(B,C):
pass
'''
DFS: A->B->D->C (不符合子类查到不到,再去父类查找,因为有两个子类。应该BC查找完再去两者的父类D查找)
BFS: A->B->C->D (符合子类查到不到,再去父类查找)
现在看来BFS符合继承规则
'''
所以DFS 和 BFS 都不是理想的方法搜索算法。
所以Python3之后,定义了叫做C3的算法,它完美解决了上述问题。类似于需要DFS的路线用DFS,在需要BFS的
路线用BFS(实际上不是这样的,只是便于理解),我们可以使用mro来查看一个类对于方法的查询路线
看看Python真正的继承顺序,也就是MRO算法得出的顺序
class D:
pass
class B(D):
pass
class E:
pass
class C(E):
pass
class A(B,C):
pass
print(A.__mro__)
'''
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)
符合继承规则的搜索
'''
class D:
pass
class B(D):
pass
class C(D):
pass
class A(B,C):
pass
print(A.__mro__)
'''
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)
同样也符合继承规则的搜索
'''