方法解析順序 MRO

2021-10-01 10:26:41 字數 1637 閱讀 6602

方法解析順序(method resolution order -mro),是一種在多重繼承中用於確定方法搜尋順序的演算法,又稱 c3 超類線性化(superclass linearization)。python 會計算出每乙個類的 mro 列表。乙個類的 mro 列表是乙個包含了其繼承鏈上所有基類的線性順序列,並且列表中的每一項均保持唯一。當需要在繼承鏈中尋找某個屬性時,python會在 mro 列表中從左到右開始查詢各個基類,直到找到第乙個匹配這個屬性的類為止。

我們不必深究這個演算法的數學原理,它實際上就是合併所有父類的mro列表並遵循如下三條準則:

其實我們只需要知道 mro 列表中類的順序代表著類層次結構間的關係即可。

考慮如下類層次結構的 mro 列表:

class base:

def __init__(self):

print('base.__init__')

class a(base):

def __init__(self):

super().__init__()

print('a.__init__')

class b(base):

def __init__(self):

super().__init__()

print('b.__init__')

class c(a,b):

def __init__(self):

super().__init__() # only one call to super() here

print('c.__init__')

c 類的 mro 列表如下:

>>> c.__mro__

(, , ,

, )>>>

如果 python 無法為 mro 建立乙個線性化的列表,便會丟擲異常。

例如,由於父類排序不當,便可能會丟擲這樣的異常。

class base(object): pass

class a(base): pass

class b(base, a): pass

因為 mro 是在程式初始化時完成的,所以只要試圖引導程式,編譯器便會丟擲異常:

traceback (most recent call last):

file "c:/users/iwhal/desktop/pytest/mro學習.py", line 11, in class b(base, a):

typeerror: cannot create a consistent method resolution

order (mro) for bases base, a

另外,並列的基類間也需要遵循相同的順序,否則也回丟擲異常。例如下面的 a 類和 b 類,如果它們的基類排序不一致,則會丟擲異常。

class base_1: pass

class base_2: pass

class a(base_2, base_1): pass

class b(base_1, base_2): pass

class c(a, b): pass

wiki/c3_linearization

多繼承以及MRO順序

單獨呼叫父類的方法 print 多繼承使用類名.init發生的狀態 class parent object definit self,name print parent的init開始被呼叫 self.name name print parent的init結束被呼叫 class son1 parent...

多繼承以及MRO順序

個類同時繼承多個類,稱為多繼承。class 類名 類名1,類名2 多繼承關係中,當多個 類具有同名的成員,類調時該成員時先調 繼承關係中的第 個宣告的類的成員。多繼承指的是子類繼承多個父類,可以通過三種方式訪問父類的方法 1 父類名.父類方法 self 這種方式容易造成父類方法被呼叫多次的問題 菱形...

多繼承及MRO順序

super init 相對於類名.init,在單繼承上用法基本 差 但在多繼承上有區別,super方法能保證每個父類的方法只會執行一次,而使用類名的方法會導致方法被執行多次 多繼承時,使用super方法,對父類的傳引數,應該是由於python中 super的演算法導致的原因,必須把引數全部傳遞,否則...