答疑《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()