Python の staticmethod と classmethod のちがい

Python には staticmethodclassmethod というよく似たふたつのデコレータが存在します。一見わかりづらいこれらのちがいについて今回は見ていきます。

結論からざっくり言うと両者のちがいは次のとおりになるかと思います。

  • staticmethod の高機能版が classmethod
  • ふたつのちがいは「引数の扱い」
  • staticmethod ではメソッドは実引数をそのまま受け取る
  • classmethod ではクラス自身が暗黙的に第一引数として挿入される

ことばだけではわかりづらいので、例を見てみましょう。

class MyClass(object):
    @staticmethod
    def static_method(*args):
        print(*args)

    @classmethod
    def class_method(*args):
        print(*args)

MyClass.static_method(1, 3, 5)
# => 1 3 5
# 渡された引数がそのまま順に表示される

MyClass.class_method(1, 3, 5)
# => <class '__main__.MyClass'> 1 3 5
# 渡された引数の前に「クラスそのもの」が表示される

staticmethod でデコレートされたメソッドは、引数を print() すると実引数がそのまま順番に表示されます。一方、 classmethod でデコレートされたメソッドには、実引数の前にクラスをあらわすオブジェクトが渡されていることが確認できます。

・・・ということからわかるように、 classmethod では第一引数に暗黙的にクラスそのものが渡される仕組みとなっています。

この classmethod のふるまいは、インスタンスメソッドの場合と同じです。

インスタンスメソッドの場合は暗黙的に第一引数にインスタンスが挿入されるので、定義する際は、第一引数を self とするのがきまりとなっています。 classmethod を使う場合もそれと同じように、第一引数を cls とすることが慣習となっています。

@classmethod
    def class_method(cls, args):
        ...

以上です。

ちなみに staticmethodclassmethod もインスタンスから呼び出すこともできます。

参考