Python self用法詳解

RioTian發表於2020-10-02

在定義類的過程中,無論是顯式建立類的構造方法,還是向類中新增例項方法,都要求將 self 引數作為方法的第一個引數。例如,定義一個 Person 類:

class Person:
    def __init__(self):
        print("正在執行構造方法")
    # 定義一個study()例項方法
    def study(self):
        print(self,"正在學Python")
zhangsan = Person()
zhangsan.study()
lisi = Person()
lisi.study()

那麼,self 到底扮演著什麼樣的角色呢?接下來將對 self 引數做詳細的介紹。

事實上,Python 只是規定,無論是構造方法還是例項方法,最少要包含一個引數,並沒有規定該引數的具體名稱。之所以將其命名為 self,只是程式設計師之間約定俗成的一種習慣,遵守這個約定,可以使我們編寫的程式碼具有更好的可讀性(大家一看到 self,就知道它的作用)。

那麼,self 引數的具體作用是什麼呢?打個比方,如果把類比作造房子的圖紙,那麼類例項化後的物件是真正可以住的房子。根據一張圖紙(類),我們可以設計出成千上萬的房子(類物件),每個房子長相都是類似的(都有相同的類變數和類方法),但它們都有各自的主人,那麼如何對它們進行區分呢?

當然是通過 self 引數,它就相當於每個房子的門鑰匙,可以保證每個房子的主人僅能進入自己的房子(每個類物件只能呼叫自己的類變數和類方法)。

如果你接觸過其他物件導向的程式語言(例如 C++),其實 Python 類方法中的 self 引數就相當於 C++ 中的 this 指標。

也就是說,同一個類可以產生多個物件,當某個物件呼叫類方法時,該物件會把自身的引用作為第一個引數自動傳給該方法,換句話說,Python 會自動繫結類方法的第一個引數指向呼叫該方法的物件。如此,Python直譯器就能知道到底要操作哪個物件的方法了。

因此,程式在呼叫例項方法和構造方法時,不需要手動為第一個引數傳值。例如,更改前面的 Person 類,如下所示:

class Person:
    def __init__(self):
        print("正在執行構造方法")
    # 定義一個study()例項方法
    def study(self):
        print(self,"正在學Python")
zhangsan = Person()
zhangsan.study()
lisi = Person()
lisi.study()

上面程式碼中,study() 中的 self 代表該方法的呼叫者,即誰呼叫該方法,那麼 self 就代表誰。因此,該程式的執行結果為:

正在執行構造方法
<__main__.Person object at 0x0000021ADD7D21D0> 正在學Python
正在執行構造方法
<__main__.Person object at 0x0000021ADD7D2E48> 正在學Python

另外,對於建構函式中的 self 引數,其代表的是當前正在初始化的類物件。舉個例子:

class Person:
    name = "xxx"
    def __init__(self,name):
        self.name=name

zhangsan = Person("zhangsan")
print(zhangsan.name)
lisi = Person("lisi")
print(lisi.name)

執行結果為:

zhangsan
lisi

可以看到,zhangsan 在進行初始化時,呼叫的建構函式中 self 代表的是 zhangsan;而 lisi 在進行初始化時,呼叫的建構函式中 self 代表的是 lisi。

值得一提的是,除了類物件可以直接呼叫類方法,還有一種函式呼叫的方式,例如:

class Person:
    def who(self):
        print(self)
zhangsan = Person()
#第一種方式
zhangsan.who()
#第二種方式
who = zhangsan.who
who()#通過 who 變數呼叫zhangsan物件中的 who() 方法

執行結果為:

<__main__.Person object at 0x0000025C26F021D0>
<__main__.Person object at 0x0000025C26F021D0>

顯然,無論採用哪種方法,self 所表示的都是實際呼叫該方法的物件。

總之,無論是類中的建構函式還是普通的類方法,實際呼叫它們的誰,則第一個引數 self 就代表誰。

相關文章