1. 程式人生 > 其它 >Python類定義中的@classmethod(類方法)和@staticmethod(靜態方法)的使用

Python類定義中的@classmethod(類方法)和@staticmethod(靜態方法)的使用

  之前的一篇博文詳細講解了什麼函式裝飾器(Python迭代器、生成器、裝飾器的使用)。在類的定義中,我們也常常見到裝飾器的使用,並且最常用的就是@classmethod,@staticmethod來裝飾我們自定義類的函式(方法),這兩個內建的裝飾器是什麼作用呢?

  在講解這兩種方法前我們需要只要,一般我們在類當中定義的方法都是例項方法,定義中都需要帶有self關鍵字,要使用例項方法,必須先把我們的類例項化才能使用。比如下面的個Dog類中的name方法。

class Dog():
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def dogname(self):
        print("我是一隻狗,名叫{}".format(self.name))

dog1 = Dog("阿黃", 12)

  如果要使用例項方法dogname(),我們只能採用dog1.dogname()才能夠使用。例項方法可以訪問例項變數、類變數,使用時必須通過例項名來呼叫。

1、類方法(@classmethod)

  什麼叫做類方法呢?只要是在定義函式的時候在前面加上@classmethod那麼接下來定義的這個函式就被稱為類方法。

class Dog():
    dog_dict = {"大狗":12, "二狗":11, "三狗":20}  # 定義了一個類變數(一個字典),表示大狗有12只,二狗有11只,三狗有20只

    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def dogname(self):
        print("我是一隻狗,名叫{}".format(self.name))

    @classmethod
    def dog_number(cls):
        number = 0 
        for item in cls.dog_dict.items():
            number += item[1]
        print('總共有{}只狗'.format(number))

    

dog1 = Dog("阿黃", 12)
dog2 = Dog("二黃", 7)
dog1.dog_number()
Dog.dog_number()

  執行結果:

  類方法不是因為具體的哪個例項而改變,因此在定義時必須使用cls(類變數)作為第一個引數(大家可以看成self的作用,只是它表示的是一個類)。既然這個方法是類方法,那我們自然可以採用類名.dog_number()來進行呼叫,也可以採用例項名.dog_number()來進行呼叫。類方法是可以訪問類變數,當然也可以訪問例項變數(不過需要傳入引數self,並且在使用時需要把例項名傳入函式中)。

2、靜態方法(@staticmethod)

  同樣的在定義函式的時候在前面加上@staticmethod那麼接下來定義的這個函式就被稱為靜態方法,靜態方法不要求你強制傳入任何引數(例項方法必須傳入slef,類方法必須傳入cls),因此這個函式對類變數和例項變數都是一無所知,你需要自己傳入引數才能使用。呼叫的時候,可以使用例項名.方法名呼叫,或者類名.方法名呼叫。看例子

class Dog():
    dog_dict = {"大狗":12, "二狗":11, "三狗":20}  # 定義了一個類變數(一個字典),表示大狗有12只,二狗有11只,三狗有20只

    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def dogname(self):
        print("我是一隻狗,名叫{}".format(self.name))

    @classmethod
    def dog_number(cls):
        number = 0 
        for item in cls.dog_dict.items():
            number += item[1]
        print('總共有{}只狗'.format(number))

    @staticmethod
    def total_age(dogs):
        '''
        傳入一個Dog例項的list,並計算這些狗的總年齡
        '''
        total = 0
        for dog in dogs:
            total += dog.age
        return total


dog1 = Dog("阿黃", 12)
dog2 = Dog("二黃", 7)
print(dog1.total_age([dog1, dog2]))

  

3、額外知識

  1、類變數:是所有例項共享的,專屬於這個類的,換句話說只要當前這個例項時屬於A類,那麼該例項就能使用A類的所有類變數。訪問類變數得分情況,如果是在類方法中訪問類變數,那麼是使用cls.類變數名;如果是在例項方法中訪問類變數,使用slef.類變數名

  2、除了常用的@classmethod和@staticmethod是常用的自定義類函式的裝飾器,還有@property 也是常用的裝飾類函式的裝飾器,其作用是可以直接使用例項名.函式名來進行呼叫函式,不需要末尾加()了。

參考網頁:

Python小技巧#9:例項方法,類方法,靜態方法的區別?_嗶哩嗶哩_bilibili

以上內容如有錯誤,懇請指正