天天看点

4-6 类和实例属性的查找顺序----mro查找

慕课网课程:Python高级编程和异步IO并发编程

mro:Method Resolution Order

自从Python2.3后使用C3 MRO算法,关于C3 MRO算法的详情,参考The Python 2.3 Method Resolution Order

那么接下来通过之前的算法来了解一下MRO

4-6 类和实例属性的查找顺序----mro查找
4-6 类和实例属性的查找顺序----mro查找
  1. 深度优先搜索DFS

    MRO结果

    图1: A->B->D->C->E

    图2: A->B->D->C

    从结果可知,DFS对应图2菱形继承有问题。为什么这么说呢?

    加入现在有一个方法get_value, C、D中存在get_value, A、B不存在get_value, 那么当A调用get_value时,调用的就是D中的get_value方法。C中永远起不到重载D中方法的作用。因此DFS对菱形继承有问题,在python2之后改为了广度优先算法, 如下

  2. 广度优先搜索BFS

    MRO结果

    图1: A->B->C->D->E

    图2: A->B->C->D

    在BFS中图2的菱形继承问题解决了,但是图1的继承又出现了问题。

    以图1来说明,如果C和D中有一个同名的方法get_value, B和A中没有get_value方法,那么A调用get_value时,就会调用C中的方法,而实际上B和D应该看成一个整体,在B中不存在就应该去父类中搜索。因此在Python2.3后,提出了C3 MRO算法,解决了上面的两个问题

那么如何查看C3 MRO算法的搜索顺序呢, 调用__mro__属性
图:
class D(object):
    pass

class E(object):
    pass

class B(D):
    pass

class C(E):
    pass
class A(B, C):
    pass

print(A.__mro__)
#MRO顺序:A-->B-->D-->C-->E        
#结果:(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>)


图2

class D(object):
    pass

class B(D):
    pass

class C(D):
    pass
class A(B, C):
    pass

print(A.__mro__)
# MRO顺序:A-->B-->C-->D
#结果:(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)