zoukankan      html  css  js  c++  java
  • Method Resolve Order (MRO)

    
    
    
    
    Method Resolve Order (MRO) - 类对象属性的解析顺序
    Python 支持多重继承, 此时就需要解决按照何种顺序来解析属性的问题.
    类的继承关系在一个特殊的类属性中指定(__mro__).这个属性的作用是按照序列出类及其超类, python 会按照这个顺利搜索方法。
    任何实现了多重继承的语言都要处理潜在的命名冲突问题,这种冲突由不相关的父类实现的同名方法所引起的,称为'菱形问题'。

    举个例子,
     1 class A(list):
     2     def disp(self):
     3         print('Class A - disp')
     4 
     5 class B(list):
     6     def disp(self):
     7         print('Class B - disp')
     8 
     9     def dispB(self):
    10         print('Class B - dispB')
    11 
    12 class C(A):
    13     pass
    14 
    15 class D(C, B):
    16     pass
    17 
    18 if __name__ == '__main__':
    19     abc = D()
    20     abc.disp()
    21     abc.dispB()
    22     print(D.__mro__)
    23     print(C.__mro__)
    24     print(B.__mro__)
    25     print(A.__mro__)
    26 
    27 '''
    28 Output,
    29     Class A - disp
    30     Class B - dispB
    31     (<class '__main__.D'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'list'>, <class 'object'>)
    32     (<class '__main__.C'>, <class '__main__.A'>, <class 'list'>, <class 'object'>)
    33     (<class '__main__.B'>, <class 'list'>, <class 'object'>)
    34     (<class '__main__.A'>, <class 'list'>, <class 'object'>)
    35 '''

    D 的基类都实现了 disp 方法。当实例 abc 调用 disp() 方法的时候,是运行 A 或者 B 中的 disp 方法呢?
    Python 内部首先完成对 D 这个类的 MRO 顺序的建立. 这个顺序存储在 D.__mor__ 属性中, 其为一个 tuple 对象,
    依次存放着 class 对象. 这个 tuple 中 class 对象的顺序就是 Python 虚拟机在解析 D 这个类的属性时的顺序。
    最终这个 tuple 将被保存在 PyTypeObject.tp_mro 中.

    示例中各个类的继承顺序,
    D -> C -> A -> B -> list -> object
    C -> A -> list -> object
    B -> list -> object
    A -> list -> object

    即,
    (<class '__main__.D'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'list'>, <class 'object'>)
    (<class '__main__.C'>, <class '__main__.A'>, <class 'list'>, <class 'object'>)
    (<class '__main__.B'>, <class 'list'>, <class 'object'>)
    (<class '__main__.A'>, <class 'list'>, <class 'object'>)

    注, MRO 设计到 '深度优先' 和 '广度优先' 两个概念.可以把这两个概念想象成两个维度. 深度优先 为 纵向维度, 广度优先 为 横向维度.

    以示例为例,
    D - C - B - list - object
    | | | |
    A list object object
    | |
    list object
    |
    object

    在 横向上(广度优先概念), 如果实例 abc 调用 disp 方法, 最终会运行 class B 中的 disp 属性.
    在 纵向上(深度优先概念), 如果实例 abc 调用 disp 方法, 最终会运行 class A 中的 disp 属性.
    MRO 是 深度优先搜索
     
      
  • 相关阅读:
    港股实时行情数据
    A股实时行情数据
    A股历史行情数据 API 接口
    公募开放式基金历史数据
    历年奥运比赛数据 API 接口
    手机归属地查询 API 接口
    获取公众号文章封面 API 接口
    公众号头条文章 API 接口
    P3572 [POI2014]PTA-Little Bird
    CF1325D Ehab the Xorcist
  • 原文地址:https://www.cnblogs.com/zzyzz/p/7504610.html
Copyright © 2011-2022 走看看