今天小蝦也是才接觸到這個super函數,感覺有點繞,所以還是決定寫一下。
先說一下super函數的工作原理:
def super(cls,inst): # 其中,cls代表類,inst代表實例,上面的代碼做了兩件事:
mro = inst.__class__.mro() # 1. 獲取inst的MRO列表
return mro[mro.index(cls) + 1] # 2. 查找cls 在當前MRO列表中的index,並返回它的下一個類, 即mro[index + 1]
當你使用super(cls,inst)時,python會在Inst的MRO列表上 搜索cls的下一個類
class Animal (object):
def run(self):
print("動物跑起來了")
class Dog(Animal):
def run(self):
print("小狗跑起來了")
def wang(self):
# super調用父類的方法
# 根據指定的類,在類繼承鏈接獲取下一個類
# 1.Dog 表示根據指定類找類繼承鏈中獲取下一個類
# 2.self表示self對象所對應類的類繼承鏈
# 提示:super 不一定是你直接繼承的父類
# 提示:當繼承爲單繼承則可以理解成繼承父類沒問題,多繼承就有可能不是了
# 調用的是父類的方法,但不一定是你直接繼承父類的方法
# 子類的方法與父類衝突,又想調用父類方法時,需要使用super()函數
# 一個類的MRO列表就是合併所有父類的MRO列表,並遵循以下三條原則:
# 1.子類永遠在父類前面
# 2. 如果有多個父類,會根據它們在列表中的順序被檢查
# 3. 如果對下一個類存在兩個合法的選擇,選擇第一個父類。
super(Dog, self).run()
print(self.__class__.mro())
print("汪")
dog = Dog()
dog.wang()
# 運行結果:
動物跑起來了
[<class '__main__.Dog'>, <class '__main__.Animal'>, <class 'object'>] #這個MRO列表代
#表類繼承的順序
汪
不知道小蝦弄的上面的例子看懂了沒?小蝦剛開始也是比較迷糊的,可能該去喫飯了,缺乏能量供應(哈哈......)。那小蝦又測試了一個代碼,這個代碼應該很好理解,見下面代碼段:
class Person(object):
def __init__(self):
print("進入父類Person")
print("離開父類Person")
class A_person(Person):
def __init__(self):
print("到 A_person")
super(A_person, self).__init__()
print("離開A_person")
class B_person(Person):
def __init__(self):
print("到 B_person")
super(B_person, self).__init__()
print("離開 B_person")
class C_person(A_person, B_person):
def __init__(self):
print("到 C_person")
super(C_person, self).__init__()
print("離開 C_person")
print(self.__class__.mro())
c = C_person()
# 運行結果爲:
到 C_person
到 A_person
到 B_person
進入父類Person
離開父類Person
離開 B_person
離開A_person
離開 C_person
[<class '__main__.C_person'>, <class '__main__.A_person'>, <class '__main__.B_person'>, <class '__main__.Person'>, <class 'object'>]
通過上面的例子,不知道明白了super的用法了沒。我稍微解釋一下(小蝦的理解呀,不知道對不!):
(1)C _person繼承A_person 和 B_person。
(2)通過self.__class__.mro()的結果是:[<class '__main__.C_person'>, <class '__main__.A_person'>, <class '__main__.B_person'>, <class '__main__.Person'>, <class 'object'>]可以知道類的MRO列表,即類的訪問順序。
(3)可知先訪問c_person類的__init__()函數,輸出:到c_person ,走到super()這個函數,訪問(4)
(4)在根據(2)中MRO列表,可知道訪問A_person ,輸出:到A_person。走到super這個函數,訪問(5)
(5)在根據(2)中MRO列表,可知道訪問B_person ,輸出:到B_person。走到super()這個函數,訪問(6)
(6)在根據(2)中MRO列表,可知道訪問Person,輸出:進入父類Person;離開父類Person
(7)依次在輸出:離開 B_person;離開A_person;離開 C_person
不知道寫到這兒,明白了嗎?小蝦在這兒,算是明白了。代碼這方面還是勤加練習吧!要能用到,可能就不會忘的那麼快啦!