Python super 詳解 最簡單的解釋

2021-10-07 13:38:58 字數 3760 閱讀 2614

首先提一下,經典類和新式類。在python2中,如果定義類的方式是 class myclass:   那麼該類叫做經典類,如果定義類的方式為class myclass(object): 那麼該類為新式類。在python3中,上面兩種方式定義出來的類都叫新式類。本文是基於新式類來進行講解的。

正文:python 中的super()是用於呼叫父類(或父類的父類...)方法的 函式,主要用於多繼承,單繼承問題不大。下面是乙個多繼承例項,繼承關係為菱形繼承, 仔細觀察下面三個例項:

#例項一:

class a(object):

def __init__(self):

print("class ---- a ----")

class b(a):

def __init__(self):

print("class ---- b ----")

super(b, self).__init__()

class c(a):

def __init__(self):

print("class ---- c ----")

super(c, self).__init__()

class d(b, c):

def __init__(self):

print("class ---- d ----")

super(d, self).__init__()

d = d()

'''#輸出結果:

class ---- d ----

class ---- b ----

class ---- c ----

class ---- a ----

'''

#coding=utf-8

#例項二: 更改一下類d的super函式:

class d(b, c):

def __init__(self):

print("class ---- d ----")

super(b, self).__init__()

d = d()

'''#輸出結果:

class ---- d ----

class ---- c ----

class ---- a ----

'''

# 例項三: 再更改一下類d的super函式:

class d(b, c):

def __init__(self):

print("class ---- d ----")

super(c, self).__init__()

d = d()

'''# 輸出結果:

class ---- d ----

class ---- a ----

'''

如果你認為super()函式就是 呼叫父類的方法,那你可能想不通後面兩個例項。原因是,super()和父類沒有實質性的關聯。如果想要搞懂super()函式的執行原理,那一定要先搞懂__mro__屬性,__mro__是method resolution order,中文方法解析順序。單繼承中super()函式使用比較簡單的原因 也是因為__mro__比較簡單,多繼承的__mro__就稍微複雜了,總之__mro__的目的就是 按照一定順序,保證父類的函式只呼叫一次

我們來先列印一下 它的屬性值,再次修改類d的super函式:

class d(b, c):

def __init__(self):

print(d.__mro__)

print("class ---- d ----")

super(d, self).__init__()

d = d()

'''#輸出結果:

(, , , , )

class ---- d ----

class ---- b ----

class ---- c ----

class ---- a ----

'''

從列印結果可以看出,__mro__是乙個元組,類d的__mro__順序是  d -> b -> c -> a -> object。敲黑板(重點):如果在類d中 呼叫super()函式時 傳入的第乙個引數是d,那麼super()函式就會在__mro__裡從d的上一級開始查詢,它的上一級是b, 那麼super(d, self).__init__() 就呼叫b的__init__()函式,b的__init__()函式裡又呼叫了b的super()函式,super(b, self).__init__(), 那就從b的上一級開始查詢,b的上一級是c, 以此類推,然後是a,最後是object。於是例項一也就解釋清楚了。

例項二中 類d的super()方法第乙個引數傳入的是 b ,那麼根據__mro__順序開始查詢,b的上一級是c,c的上一級是a,所以例項二的列印順序是 d - > c -> a

例項三也就不難解釋了。

最後再講一下super()函式的引數,該函式需要兩個引數,第乙個是類名,第二個一般都是self,但偶爾也有cls的情況,在:python 3 可以使用直接使用super().*** 代替super(class, self).***, 比如:

class d(b, c):

def __init__(self):

print(d.__mro__)

print("class ---- d ----")

super().__init__()

d = d()

'''#輸出結果:

(, , , , )

class ---- d ----

class ---- b ----

class ---- c ----

class ---- a ----

'''

經典類的mro方法是採用 從左至右的深度優先遍歷 演算法,重複留前者按照深度遍歷,其順序為 [d, b, a, object, c, a, object],重複者只保留前面乙個,因此變為 [d, b, a, object, c]

新式類的mro方法是採用 從左至右的深度優先遍歷 的演算法,重複留後者

按照深度遍歷,其順序為 [d, b, a, object, c, a, object],重複者只保留後面乙個,因此變為 [d, b, c, a, object]

pythonsuper 函式的詳解

目錄 python是一門物件導向的語言,定義類時經常要用到繼承,在類的繼承中,子類繼承父類中已經封裝好的方法,不需要再次編寫,如果子類如果重新定義了父類的某一方法,那麼該方法就會覆蓋父類的同名方法,但是有時我們希望子類保持父類方法的基礎上進行擴充套件,而不是直接覆蓋,就需要先呼叫父類的方法,然後再進...

python super用法及原理詳解

概念 super作為python的內建函式。主要作用如下 例項在單個繼承的場景下,一般使用super來呼叫基類來實現 下面是乙個例子 class mammal object def wugbzinit self,mammalname print mammalname,is a warm bloode...

python super函式使用方法詳解

python內建函式super 主要用於類的多繼承中,用來查詢並呼叫父類的方法,所以在單重繼承中用不用 super 都沒關係 但是,使用 super 是乙個好的習慣。一般我們在子類中需要呼叫父類的方法時才會這麼用 super type,object or type 引數 type 類,一般是類名 o...