(譯文)Python中的staticmethod與classmethod


原文是stackoverflow的一則高票回答,原文鏈接 可能之前也有人翻譯過,但是剛好自己也有疑惑,所以搬運一下,個人水平有限所以可能翻譯存在誤差,歡迎指正(如侵刪)。


盡管classmethodstaticmethod非常的相似,但是兩者在具體的使用上還是有着細微的差別:classmethod必須使用類對象作為第一個參數,而staticmethod則可以不傳遞任何參數。

讓我們通過實際的例子來看看。

樣板

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

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類實例。我們不得不在項目的不同地方做這些事情。

所以我們必須要做到:

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

得到:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM