(譯文)Python中的staticmethod與classmethod

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


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

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

樣板

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

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表示)對象

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

類方法

有一些能夠經過使用classmethod很好解決的任務。字符串

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

因此咱們必需要作到:string

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

獲得:it

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的使用,咱們不須要訪問它所屬的類,它本質上就是一個函數,調用方式和調用函數同樣,不一樣的是它不關注對象和對象內部屬性。

相關文章
相關標籤/搜索