Home staticmethod 與 classmethod 的差異
Post
Cancel

staticmethod 與 classmethod 的差異

在 Python 的 class 裡面,除了可以直接定義 method,透過添加 decorator (裝飾器),可以定義出具有特殊功能的 method。

閱讀本文的先備知識

  1. 基本 Python 語法
  2. 一般的 class 的使用方式

本文將帶給你的內容

  1. 如何使用 @staticmethod 與 @classmethod
  2. 各 method 的使用時機

如何使用 @staticmethod 與 @classmethod

通常一個 class 會包含以下的部分

1
2
3
4
5
6
class classA():
    def __init__(self, num):
        self.num = num
    
    def print_number(self, x):
        print("printing by general method (%s, %s)" % self, x)

而 staticmethod 與 classmethod 與其他 decorator 一樣,在 method 加上即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class classA():
    def __init__(self, num):
        self.num = num
    
    def print_number(self, x):
        print("printing by general method (%s, %s)" % (self, x))
    
    @classmethod
    def class_print_number(cls, x):
        print("printing by class method (%s, %s)" % (cls, x))
    
    @staticmethod
    def static_print_number(x):
        print("printing by static method (%s)" % x)

恩對,使用上沒有什麼特別的,只是要注意 method 的輸入

  • classmethod 的輸入會從 self 變成 cls,後續會再說明
  • staticmethod 的輸入相較於一般 method,少了 self 的部分

執行以下的結果會看到各自的差異

1
2
3
4
5
6
7
8
9
> a = classA(10)
> a.print_number(1)
printing by general method (<__main__.classA object at 0x7fb6998e9080>, 1)

> a.class_print_number(1)
printing by class method (<class '__main__.classA'>, 1)

> a.static_print_number(1)
printing by static method (1)

可以發現在使用上,三種 method 都只吃一個參數,而一般 method 與 classmehtod 有設定時就產生的預設參數。那麼下個問題是,這三個 method 的使用時機。

各 method 的使用時機

這邊的時機,指的是使用上的需求,當然也可以什麼情況都使用一般的 method。下面先定義另一個 class,方便後續說明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class classEX():
    def __init__(self, num):
        self.num = num
    
    def ex_print_number(self, x):
        print("printing by general method (%s, %s)" % (self.num, x))
    
    @classmethod
    def ex_class_print_number(cls, x):
        print("printing by class method (%s, %s)" % (cls.square(x), x))
    
    @staticmethod
    def ex_static_print_number(x):
        print("printing by static method (%s)" % x)
    
    @staticmethod
    def square(x):
        return x*x

繼承 class 的輸入參數時

選擇一般的 method,並透過 self 直接調用 class 的輸入。

1
2
> example.ex_print_number(2)
printing by general method (10, 2)

調用 class 裡其他的 method,甚至是整個 class 時

選擇 classmethod,並透過 cls 調用,例如下面這個例子,就直接調用同一 class 中 square 這個 method。

1
2
> example.ex_class_print_number(2)
printing by class method (4, 2)

什麼都不需要,只是包在 class 內部

使用 staticmethod 即可

1
2
> example.ex_static_print_number(2)
printing by static method (2)

延伸閱讀

References

This post is licensed under CC BY 4.0 by the author.