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 为 深度优先搜索。
时间: 2024-09-29 01:58:29