Python 入門 21 —— 類的靜態方法、 staticmethod()

一、類的靜態方法

被 @staticmethod 裝飾過類的方法,被稱爲類的靜態方法。類的普通方法變成靜態方法之後,在調用時系統將不把類本身或對象本身作爲實參賦給形參,在靜態方法中引用類或對象的數據成員或方法,必須用“類名”或“對象名”這種硬編碼的方式。例如:

class c01:
    a=100
    
    @ staticmethod
    def fun01(x,y): print(x,y,c01.a)

c01.fun01(7,8)    # 7  8  100

既然靜態方法訪問類或對象的數據成員或方法也必須用硬編碼的方式,那與類外的函數不就沒區別了嗎?實際上,靜態方法與類外的函數的確是沒有多少區別。類的普通方法變成靜態方法之後,基本上與類就切斷了聯繫,靜態方法之所以要放在類中,通常只是這個靜態方法的主要功能與這個類相關。也就是說,靜態方法放在類中,主要是有利於組織代碼,有利於命名空間的整潔。例如在下例中,檢查一個數值是否是合格的日期或月份的函數,是一個很一般函數,放在類裏面和放在類外面都可以,但放在類裏面顯然便於管理:

class ymd():
    def __init__(self, y=0, m=0, d=0): self.y=y;self.m=m;self.d=d;

    def riqi(self):
        return self.y+'年'+self.m+'月'+self.d+'日'

    @classmethod
    def riqi2(cls,x): y, m, d=map(str,x.split('-')); return cls(y,m,d)

    @classmethod
    def riqi3(cls,x): y, m, d=map(str,x.split('/')); return cls(y,m,d)

    @ staticmethod
    def chk_m(x):
        if(x>12): print('Wrong Month:',x)
        else: print('Right Month:',x)

    @ staticmethod
    def chk_d(x):
        if(x>31): print('Wrong Day:',x)
        else: print('Right Day:',x)

d01 = ymd('2020', '01', '01')
print(d01.riqi())    # 2020年01月01日

d02 = ymd.riqi2('2020-02-02')
print(d02.riqi())    # 2020年02月02日

d03 = ymd.riqi3('2020/03/03')
print(d03.riqi())    # 2020年03月03日

ymd.chk_m(6)    # Right Month: 6
ymd.chk_m(26)    # Wrong Month: 26

ymd.chk_d(6)    # Right Day: 6
ymd.chk_d(26)    # Right Day: 26
ymd.chk_d(36)    # Wrong Day: 36

二、@property、@classmethod、@staticmethod 使用小結

1、從純編程的角度看:

(1)不想接受任何額外參數的類的方法,可用 @property 或 property() 轉變成類的屬性,這樣引用時很方便,小括號都可以不要。

(2)不想接受類對象這個實參,而只想接受類本身這個實參的類的方法,可用 @classmethod 裝飾轉變成類的類方法,這樣操作類的數據成員和方法很方便,創建類的對象也很方便。

(3)既不想接受類對象這個實參,也不想接受類本身這個實參的類的方法,也就是,不想操作類或對象的數據成員和方法,僅想在類裏面放一放的函數,可以用 @staticmethod 裝飾轉變成類的靜態方法,這樣函數定義時可以任意設置參數,省去對第一個形參的顧慮。

2、從應用的角度看:

(1)當需要保護某個私有成員時,可用 @property 或 property() 定義一個屬性,然後通過這個屬性來訪問和操作那個需要保護的私有成員。

(2)當需要在創建對象前作些預處理的工作時,可用 @classmethod 定義一個類方法,然後在這個類方法中先進行預處理,最後創建對象,並將新創建的對象返回。

(3)當需要做些與類相關的工作,但又不需要引用類或對象的數據成員和方法時,可以在類中定義一個做相關工作的方法,然後用 @staticmethod 裝飾,變成一個類的靜態方法。

3、用 @property、@classmethod、@staticmethod 裝飾,往往是爲了使編程更便捷,而不是一定要這樣做,不用它們進行裝飾,使用普通的類的方法,通常也能達到同樣的目的,但使用起來可能會稍微麻煩一些。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章