Method Resolve Order (MRO) - 类对象属性的解析顺序
Python 支持多重继承, 此时就需要解决按照何种顺序来解析属性的问题.
类的继承关系在一个特殊的类属性中指定(__mro__).这个属性的作用是按照序列出类及其超类, python 会按照这个顺利搜索方法。
任何实现了多重继承的语言都要处理潜在的命名冲突问题,这种冲突由不相关的父类实现的同名方法所引起的,称为'菱形问题'。 举个例子,
 class A(list):
def disp(self):
print('Class A - disp') class B(list):
def disp(self):
print('Class B - disp') def dispB(self):
print('Class B - dispB') class C(A):
pass class D(C, B):
pass if __name__ == '__main__':
abc = D()
abc.disp()
abc.dispB()
print(D.__mro__)
print(C.__mro__)
print(B.__mro__)
print(A.__mro__) '''
Output,
Class A - disp
Class B - dispB
(<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'>)
'''
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 是 深度优先搜索
 
  

Method Resolve Order (MRO) - 类对象属性的解析顺序的更多相关文章

  1. python添加、修改、删除、访问类对象属性的2种方法

    1.直接添加.修改.删除.访问类对象属性 class Employee (object): empCount = 0 def __init__(self, name, salary) : self.n ...

  2. Python的程序结构[2] -> 类/Class[2] -> 方法解析顺序 MRO

    方法解析顺序 / MRO (Method Resolution Order) 关于方法解析顺序(MRO)的详细内容可以参考文末链接,这里主要对 MRO 进行简要的总结说明以及一些练习示例. 经典类和新 ...

  3. Method Resolution Order – Python类的方法解析顺序

    在支持多重继承的编程语言中,查找方法具体来自那个类时的基类搜索顺序通常被称为方法解析顺序(Method Resolution Order),简称MRO.(Python中查找其它属性也遵循同一规则.)对 ...

  4. java 获取实体类对象属性值的方法

    在java中我们要获得实体类对象的属性,一般情况是将实体类中的属性私有化,然后再对外提供get()与set()方法,然后再获取实体类对象的属性的时候先把对象new出来,再用变量名.get()的方法得到 ...

  5. day 1类 对象 属性 方法

    1. 解决吃啤酒鸭的问题 第一种方式(面向过程): 1)养鸭子 2)鸭子长成 3)杀 4)作料 5)烹饪 6)吃 7)卒 第二种方式(面向对象): 1)找个卖啤酒鸭的人 2)给钱 交易 3)吃 4)胖 ...

  6. python类对象属性查找原理

    class Foo(object): def __init__(self): # 这是一个对象属性 self.obj_pro = 12 # 这是一类属性 c_pro = 11 # 这是一个静态方法 @ ...

  7. object-c计划tips-添加到类对象属性

    这个问题从网络包的内容,由于保密问题,我刚才所描述我的业余的想法. 基本的想法: 网络请求,我们应该能够使用基类BaseNetWork, 然后由派生类继承BaseNetWork,并实现一些特殊的方法. ...

  8. java类中属性优先执行顺序

    1.父类静态代码块 (  java虚拟机加载类时,就会执行该块代码,故只执行一次) 2 .子类静态代码块 (  java虚拟机加载类时,就会执行该块代码,故只执行一次) 3. 父类属性对象初始化 4. ...

  9. ECMAScript5之JSON对象属性的遍历顺序

    测试浏览器 Chrome.Safari 一 键可以用parseInt解析成整数的,按数值升序顺序. var intObj = { '3.3' : 3.3, '2' : 222, '1' :111 } ...

随机推荐

  1. spring get方法 中文(UTF-8)乱码

    问题: 前端用Get方法进行如下请求: 在浏览器中输入:http://localhost:8080/dmaList/ExportBySQL?sql=&names=分区级别&size=1 ...

  2. PQSQL 按照时间进行分组

    按照时间分组时一般是按照年.月.日进行分组,不会把时分秒也算进去,所以需要把时间戳提取出所需要的时间段,本质上是把时间戳格式化成对应形式的字符串,这个过程需要用to_char(timestamp, t ...

  3. Spark 配置参数

    SparkConfiguration 这一章节来看看 Spark的相关配置. 并非仅仅能够应用于 SparkStreaming, 而是对于 Spark的各种类型都有支持. 各个不同. 其中中文参考链接 ...

  4. szTom's Code Style

    介绍szTom在C++中使用的代码风格. 头文件 必须使用using namespace std; 如果是C头文件,必须使用c前缀文件名. #include <cstdio> 而不是 #i ...

  5. JS中Cookie、localStorage、sessionStorage三者的区别

    cookie:大小4k,一般由服务器生成,可设置失效时间,关闭浏览器后失效,与服务器通信时:每次都会携带HTTP头中,如果使用cookie保存过多数据会带来性能问题 localhostStorage: ...

  6. 最小生成树kruskal 知识点讲解+模板

    0.前言 因为本人太蒟了 我现在连NOIP的初赛都在胆战心惊 并且我甚至连最小生成树都没有学过 所以这一篇博客一定是最详细的QAQ 哈哈 请您认真看完如果有疏漏之处敬请留言指正 感谢! Thanks♪ ...

  7. java 大数的学习

    import java.math.*; import java.util.*; public class study { public static void main(String[] args) ...

  8. crawler碎碎念5 豆瓣爬取操作之登录练习

    import requests import html5lib import re from bs4 import BeautifulSoup s = requests.Session() #这里要提 ...

  9. selenium chrome headless无界面引擎

    注意:PhantomJS已被舍弃 chrome headless 在打开浏览器之前添加参数 import time import sys from selenium import webdriver ...

  10. java.lang.IllegalArgumentException: clusterListener can not be null

    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb. ...