答疑《python的CLS》
- 2019 年 10 月 6 日
- 筆記
這兩天有個朋友看到這樣的一個程式碼,問我啥意思,我第一眼看上去也是比較懵的(原諒我比較菜,見識短),cls後面竟然多了個括弧???,直接開始用了????

於是小編網路一番搜尋,得出了答案。
要談cls()咱們先從python的classmethod說起。
python的classmethod叫做python的累方法,是只需要在普通方法上加上@classmethod這樣一個裝飾器就可以啦(裝飾器是什麼就別問我了,之前推文寫過,可以翻一番歷史推文)
普通方法
def hello(self): pass
類方法
@classmethod def hello(cls): pass
如上程式碼,這就是一個最簡單的類方法,這時候可以對比一下兩個方法有什麼不同?
除了多了一個classmethod裝飾器,其實還有括弧裡面的參數形式發生類變化,由self變成了cls,雖然我們之前說過()裡面的參數隨便叫什麼都可以,self只不過是我們約定俗成的一種寫法,但是在這裡,從self變成了cls並不是形式上的變化,而是根本上的變化。
為什麼這麼說呢?
self所代表的其實是對象的指針,它可以指向任意一個對象。在實例化對象的時候self就會變成對象實例。
cls所代表的東西代表的其實是一個類本身,它可以用來調用類自己的屬性和類自己的方法。
下面可以看一個例子:
class Hello(): a = 1 def h1(self): print ('hello 1111') @classmethod def h2(cls): print ('hello 22222')
現在我們定義了一個Hello類,在Hello類裡面有h1,h2兩個方法,其中h2是類方法,現在cls表演的時刻到了!
如果我想在h2裡面獲得類裡面的a屬性,我可以直接去訪問嗎?

運行結果:

答案是不行的,那怎麼辦呢?
答案是使用cls去獲取a這個屬性啦
@classmethod def h2(cls): print ('hello 22222') print (cls.a)
結果:

可以正常訪問到屬性,這點其實和self是一樣的,普通方法訪問類中的屬性的時候也是藉助於self來訪問的。
下面接著看,如果我需要在h2裡面調用h1方法呢?
直接寫h1?
估計大家都猜到了,不行,
那就用cls
@classmethod def h2(cls): print ('hello 22222') print (cls.a) cls.h1()
這樣寫,我們來看一下結果

很明顯是有問題的
那應該怎麼辦??
那我們回到一開始看看,一開始的問題cls後面為啥有括弧??
我們把括弧加上去試試。
@classmethod def h2(cls): print ('hello 22222') print (cls.a) cls().h1()
運行一下:

運行沒有問題,可以調用
那為什麼會這樣呢?
cls其實在這個裡面代表的就是一個類本身,可以就把cls()看作是Hello這個類,那調用方法直接點那個方法不就可以了嗎?所以,cls()這個東西其實就是這個類,但是現在的調用和我們一開始的調用不一樣啊?
在一開始的圖片中cls()裡面是有參數的呀,我們這個沒有參數,那個有參數的是怎麼回事呢?
相信已經有一部分人已經知道了,這些參數其實就是在構造方法中傳入的參數啊!
class Hello(): def __init__(self, b, c): self.b = b self.c = c def h1(self): print ('hello 1111') @classmethod def h2(cls): print ('hello 22222') cls(1, 2).h1() Hello.h2()
所以,現在知道cls是什麼東西了吧!
cls這個參數表示自身類,它的作用有:調用類的屬性,類的方法,實例化對象等。
最後再說一下:類方法可以同時被對象和類本身調用哦!
對於剛剛的Hello類
hi = Hello(3,2) # 對象調用 hi.h2() # 類直接調用 Hello.h2()