python3 MRO算法以及super函数的入门到中等理解【非深入研究】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tobe_numberone/article/details/81451421

前言

本群的作业,没有指定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'>)
同样也符合继承规则的搜索
'''

猜你喜欢

转载自blog.csdn.net/tobe_numberone/article/details/81451421