天天看點

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是什麼東東?小結