python staticmethod and classmethod
盡管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明顯的區別。classmethod 必須有一個指向 類對象 的引用作為第一個參數,而 staticmethod 可以沒有任何參數。
讓我們看幾個例子。
class Date(object): def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year
很明顯,這個類的對象可以存儲日期信息(不包括時區,假設他們都存儲在 UTC)。
這里的 init 方法用於初始化對象的屬性,它的第一個參數一定是 self,用於指向已經創建好的對象。
1. Class Method
利用 classmethod 可以做一些很棒的東西。
比如我們可以支持從特定格式的日期字符串來創建對象,它的格式是 (‘dd-mm-yyyy’)。很明顯,我們只能在其他地方而不是 init 方法里實現這個功能。
大概步驟:
- 解析字符串,得到整數 day, month, year。
- 使用得到的信息初始化對象
代碼如下
day, month, year = map(int, string_date.split('-')) date1 = Date(day, month, year)
理想的情況是 Date 類本身可以具備處理字符串時間的能力,解決了重用性問題,比如添加一個額外的方法。
C++ 可以方便的使用重載來解決這個問題,但是 python 不具備類似的特性。 所以接下來我們要使用 classmethod 來幫我們實現。
@classmethod def from_string(cls, date_as_string): day, month, year = map(int, date_as_string.split('-')) date1 = cls(day, month, year) return date1 date2 = Date.from_string('11-09-2012')
讓我們在仔細的分析下上面的實現,看看它的好處。
我們在一個方法中實現了功能,因此它是可重用的。 這里的封裝處理的不錯(如果你發現還可以在代碼的任意地方添加一個不屬於 Date 的函數來實現類似的功能,那很顯然上面的辦法更符合 OOP 規范)。 cls 是一個保存了 class 的對象(所有的一切都是對象)。 更妙的是, Date 類的衍生類都會具有 from_string 這個有用的方法。
2. Static method
staticmethod 沒有任何必選參數,而 classmethod 第一個參數永遠是 cls, instancemethod (實例方法)第一個參數永遠是 self。
@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 # usage: is_date = Date.is_date_valid('11-09-2012')
所以,從靜態方法的使用中可以看出,我們不會訪問到 class 本身 – 它基本上只是一個函數,在語法上就像一個方法一樣,但是沒有訪問對象和它的內部(字段和其他方法),相反 classmethod 會訪問 cls, instancemethod 會訪問 self。
總結:需要實例化,就普通方法;不需要類實例化,但是會用到類,就用類方法;如果跟類完全沒關系,就用靜態方法。
From:http://python.jobbole.com/88765/