(譯文)Python中的staticmethod與classmethod

原文是stackoverflow的一則高票回答,原文連接
可能以前也有人翻譯過,可是恰好本身也有疑惑,因此搬運一下,我的水平有限因此可能翻譯存在偏差,歡迎指正(如侵刪)。python


儘管classmethodstaticmethod很是的類似,可是二者在具體的使用上仍是有着細微的差異:classmethod必須使用類對象做爲第一個參數,而staticmethod則能夠不傳遞任何參數。函數

讓咱們經過實際的例子來看看。spa

樣板

讓咱們假設有處理日期信息的類:翻譯

class Date(object): day = 0 month = 0 year = 0 def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year

這個類很顯然能夠被用來存儲某些日期信息(不考慮時區信息;讓咱們假設全部的日期都用UTC表示)code

這裏定義了__init__,典型的類實例初始化方法,它做爲典型的instancemethod接受參數,其中第一個傳遞的必要參數是新建的實例自己。對象

類方法

有一些能夠經過使用classmethod很好解決的任務。繼承

假設咱們有不少('dd-mm-yyyy')格式字符串的日期信息,想要把它們建立成Date類實例。咱們不得不在項目的不一樣地方作這些事情。字符串

因此咱們必需要作到:get

  1. 分析獲得的年月日字符串,把它們轉化成三個整形變量或者擁有三個元素的元組的變量。
  2. 經過傳遞這些值實例化Date

獲得:string

day, month, year = map(int, string_date.split('-')) date1 = Date(day, month, year)

C++擁有重載的特性能夠達到這種目的,可是Python缺少此類特性。因此,python使用classmethod的方式。讓咱們嘗試一種另類的構造函數。

 @classmethod def from_string(cls, date_as_string): day, month, year = map(date_as_string.split('-')) date1 = cls(day, month, year) return date1 date2 = Date.from_string('11-09-2012')

進一步分析一下以上代碼的執行,以及它的優點:

1.在一個地方解析日期字符串而且重複使用它。
2.作到很好的封裝(相對於把執行字符串解析做爲一個單獨的函數在任何地方執行,這裏使用的方法更符合OOP的範式)
3.cls表示類對象,而不是類實例。這樣很酷,由於若是咱們繼承Date類,那麼全部的子類也都將擁有from_string這個方法。

靜態方法

那麼staticmethod又是什麼呢?它和classmethod很是的類似,可是不強制要求傳遞參數(可是作的事與類方法或實例方法同樣)。

讓咱們來看一個使用的例子。

咱們有一個日期字符串須要以某種方式驗證。這個任務與以前同樣要定義在Date類內部,可是不要求實例化它。

靜態方法在這種狀況下就很是有用。看一下下面這個代碼片斷:

 @staticmethod def is_date_valid(date_as_string): day, month, year = map(int, date_as_string_split('-')) return day <= 31 and month <= 12 and year <= 3999 is_date = Date.is_date_valid('11-09-2012')

如今正如咱們瞭解到的staticmethod的使用,咱們不須要訪問它所屬的類,它本質上就是一個函數,調用方式和調用函數同樣,不一樣的是它不關注對象和對象內部屬性。

相關文章
相關標籤/搜索