python中的super是什么?


技術背景

python中的super,名為超類,可以簡單的理解為執行父類的__init__函數。由於在python中不論是一對一的繼承,還是一子類繼承多個父類,都會涉及到執行的先后順序的問題。那么本文就着重看下super的具體作用。

案例測試

通過設計這樣一個案例,我們可以明確super的前后邏輯關系:先定義一個父類initial,在這個父類中有參數值param和函數func,然后用子類new來繼承父類initial。繼承之后,在子類的__init__函數中super執行的前后去打印參數值param和函數func的返回值,相關代碼如下所示:

# 定義父類
class initial(object):
    def __init__(self):
        print ('This print is from initial object')
        # 定義父類參數
        self.param = 3

    # 定義父類函數
    def func(self):
        return 1

# 定義子類
class new(initial):
    def __init__(self):
        print ('This print is from new object')
        # 打印子類函數值
        print (self.func())
        # 執行父類初始化函數
        super(new, self).__init__()
        # 打印父類參數值
        print(self.param)
        self.param = 4

    # 定義子類函數
    def func(self):
        return 2

if __name__ == '__main__':
    new()

代碼的執行結果如下所示:

This print is from new object
2
This print is from initial object
3

結果分析

首先我們注意到,父類initial中的__init__函數內的打印語句,是在super之后才輸出的,這說明了,super函數是在執行父類的初始化操作。那么如果沒有執行supernew子類對initial父類的繼承體現在哪里呢?答案就是父類的成員函數,比如這樣的一個案例:

class initial(object):
    def __init__(self):
        print ('This print is from initial object')
        self.param = 3
    def func(self):
        return 1

class new(initial):
    def __init__(self):
        print ('This print is from new object')
        print (self.func())
        super(new, self).__init__()
        print(self.param)
        self.param = 4

if __name__ == '__main__':
    new()

其實就是刪掉了子類中重載的成員函數,那么得到的結果如下:

This print is from new object
1
This print is from initial object
3

可以發現在執行super之前就可以打印父類的func函數的函數值。所以python中繼承的邏輯是這樣的:

\[initial.func()\\ \Downarrow\\ new.\_\_init\_\_()\\ \Downarrow\\ new.func()/new.param\\ \Downarrow\\ super()\\ \Downarrow\\ initial.\_\_init\_\_()/initial.param\\ \Downarrow\\ new.\_\_init\_\_()/new.param \]

也正是因為只有執行了super才能初始化父類中的成員變量,因此如果在super之前是無法訪問父類的成員變量的。

總結概要

本文通過一個python的實際案例的設計,來講解python面向對象的技術——類的繼承中必用的super函數的邏輯。其實我們可以把python中類的繼承理解成這樣的一個過程:當我們在括號中明確了父類時,其實已經引用了父類的成員函數,但是並沒有執行父類的初始化函數。在執行子類的初始化函數的同時,會檢查是否重載了父類的成員函數,如果重載則會直接覆蓋。而只有在執行了super之后,才相當於執行了父類的初始化函數,此時才可以訪問父類的成員變量。

版權聲明

本文首發鏈接為:https://www.cnblogs.com/dechinphy/p/super.html

作者ID:DechinPhy

更多原著文章請參考:https://www.cnblogs.com/dechinphy/

打賞專用鏈接:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

騰訊雲專欄同步:https://cloud.tencent.com/developer/column/91958


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM