python 中@staticmethod 和 @classmethod總結

這幾年代碼沒少寫,但是對於@staticmethod 和 @classmethod並沒有一個系統的理解,

只知道一些大家都知道的特性。

python 中@staticmethod 和 @classmethod總結

示例代碼


  • 實例方法

只能通過類的實例化對象進行調用 Person().breath()

  • 靜態方法

不僅可以通過類名+方法名或類名+屬性名訪問, 也可以通過實例化對象訪問Person.run()

  • 類方法

跟靜態方法調用類似,也是通過類名+方法名或類名+屬性名訪問 Person.eat(),同樣也可以通過類的實例化對象訪問。

以上是普遍都知道的特性。最近我又有了新的認識,僅此記錄一下。

區別

1 、@staticmethod修飾的是一個靜態方法,不可以訪問類的實例方法和變量,

也不可以訪問類方法和類變量。當你定義的方法與類的關係不大,不需要訪問

類屬性和方法時,用@staticmethod就很合適

那麼如果我就是想通過靜態方法訪問類成員可以嗎?

答案當然是可以的,你只需要在方法中顯示的用類.方法名。

上圖中 靜態方法run 如果想要方位類變量 y, 就必須顯示的Person.y這樣調用


python 中@staticmethod 和 @classmethod總結


但是這也會使得代碼看起來非常彆扭。

因此,這種情況下不適合定義成靜態方法,@classmethod更合適

2 、@classmethod 修飾的是一個類方法,cls代表類本身(本例中是Person), 因此

訪問類變量類的靜態方法和類方法非常方便。 例如上圖中cls.y就能輕鬆訪問類變量y

所以如果一個方法可能會用到類成員變量或類成員方法用@classmethod更合適

__init__中的變量和__init__之外的變量有什麼區別呢?

  • __init__中的變量

這些變量都是屬於類的實例對象,比如你每實例化一個Person對象,那麼每個Person對象都保留一份x變量值,每個Person對象的值變化不會影響別的類例如下圖代碼:

python 中@staticmethod 和 @classmethod總結

p對象的x重新賦值後,並沒有影響到q對象的x值。

  • __init__之外的變量

這些變量就屬於類的變量,類的實例化對象也能訪問類變量,並且每個實例化對象

都保留一份類的變量,該類的變量只能由類管理,類的實例化對象只克隆保留一份。

python 中@staticmethod 和 @classmethod總結

p.y 重新賦值後,再次訪問Person.y 發現值未發生變化

舉個例子來講一下在設計一個類的時候,變量寫在__init__之內還是之外

比如有一個長方形類,它有以下幾個屬性

side_num(邊的個數), length (長),width(寬)

那麼 side_num 適合定義在__init__之外,因為不管是長方形還是正方形(長寬相等的長方形)

他們都是四邊形,也就是說side_num始終都是4。每個實例都有這個屬性,這個屬性有類統一維護

length,width 適合定義在__init__之中,因為每個長方形都有不同的長和寬

如果你有更好助人理解的例子,歡迎在下方評論留言討論,感謝!!!


分享到:


相關文章: