天天看点

python类中的super,原理如何?MRO是什么东东?小结

下面这个URL解释得比较清楚。

http://python.jobbole.com/86787/?utm_source=group.jobbole.com&utm_medium=relatedArticles

================

首先得说明的是,Python的类分为经典类 和 新式类

经典类是python2.2之前的东西,但是在2.7还在兼容,但是在3之后的版本就只承认新式类了

新式类在python2.2之后的版本中都可以使用

经典类是默认没有派生自某个基类的,而新式类是默认派生自<code>object</code>这个基类的:

1

2

3

4

5

6

# old style

class A():pass

# new style

class A(obejct):pass

2.经典类在类多重继承的时候是采用<code>从左到右深度优先</code>原则匹配方法的..而新式类是采用<code>C3算法</code>(不同于广度优先)进行匹配的

3.经典类是没有<code>__MRO__</code>和<code>instance.mro()</code>调用的,而新式类是有的.

因为在经典类中的多重继承会有些问题…可能导致在继承树中的方法查询绕过后面的父类:

在经典类中,你如果要访问父类的话,是用类名来访问的..

7

8

class A():

    def __init__(self):

        print "A"

class B(A):

        print "B"

        A.__init__(self)  #python不会默认调用父类的初始化函数的

这样子看起来没三问题,但是如果类的继承结构比较复杂,会导致代码的<code>可维护性很差</code>..

所以新式类推出了<code>super</code>这个东西…

        super(B,self).__init__()

事实上,对于你定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,它代表了类继承的顺序,我们可以使用下面的方式获得某个类的 MRO 列表:

子类永远在父类前面

如果有多个父类,会根据它们在列表中的顺序被检查

如果对下一个类存在两个合法的选择,选择第一个父类

避免多重继承

super使用一致

不要混用经典类和新式类

调用父类的时候注意检查类层次

事实上,<code>super</code> 和父类没有实质性的关联。

<code>super(cls, inst)</code> 获得的是 cls 在 inst 的 MRO 列表中的下一个类。

测试代码:

输出:

python类中的super,原理如何?MRO是什么东东?小结