【Python】classmethod(クラス・メソッド)の書き方【入門第37回】

138, 2019-08-29

目次

classmethod(クラス・メソッド)とは?

こんにちは、narupoです。

今回もクラスの機能ですが、classmethod(クラス・メソッド)という機能をご紹介します。
このclassmethodstaticmethod進化版みたいなやつです。
扱えるようになるとstaticmethodよりも柔軟にクラスを設計することが可能です。

具体的には↓を見ていきます。

  • classmethodの書き方

  • classmethodの特徴

  • staticmethodとの違い

classmethodの書き方

classmethodは↓のように書きます。

:::text
class クラス名:
    @classmethod
    def メソッド名(cls):
        pass

たとえばCatというクラスにsayというclassmethodを書きたい場合は↓のようにします。

:::python
class Cat:
    @classmethod
    def say(cls):
        print('にゃーん')

staticmethodと違い、メソッドの第一引数にclsという見慣れない引数があります。
これがclassmethodの特徴です。

classmethodの特徴

classmethodは第1引数にクラスが入ります。
たとえば↓のようなクラスがあります。

:::python
class Cat:
    @classmethod
    def say(cls):
        print(cls)

このクラスのclassmethodであるsayメソッドを使ってみましょう。

:::python
Cat.say()

↑のようにclassmethodstaticmethodのようにクラスをインスタンス化しなくても呼び出すことができます。
↑のコードの実行結果は↓のようになります。

<class '__main__.Cat'>

↑のように第1引数clsがクラスであることがわかります。
これは、インスタンスではなくてクラスそのものなので注意してください。

clsはクラスなので、この引数からクラス変数やstaticmethodを参照することができます。
たとえば↓のようにです。

:::python
class Cat:
    NAME = 'ミケ'

    @classmethod
    def say(cls):
        print(cls.NAME + 'だよ☆彡')

↑のコードの実行結果はミケだよ☆彡になります。

staticmethodとの違い

ここまで見た感じだと、staticmethodと大して違いがなさそうに見えます。
しかし、classmethodには大きな特徴がもう1つあります。
それは、第1引数には継承が反映されたクラスが渡されるということです。
たとえば↓を見てください。

:::python
class Animal:
    @classmethod
    def say(cls):
        print(cls)

class Cat(Animal):
    @classmethod
    def say(cls):
        print(cls)

Animal.say()
Cat.say()

↑のコードの実行結果は↓のようになります。

<class '__main__.Animal'>
<class '__main__.Cat'>

↑のクラスCatAnimalを継承したクラスです。
↑のようにCatsayメソッドの第1引数にはCatクラスが入ります。

さらに↓のようにクラス変数NAMEを作ります。

:::python
class Animal:
    NAME = 'ぬえ'

    @classmethod
    def say(cls):
        print(cls.NAME + 'です。。')

class Cat(Animal):
    NAME = 'ミケ'

    @classmethod
    def say(cls):
        print(cls.NAME + 'だよ☆彡')

Animal.say()
Cat.say()

↑のコードの実行結果は↓のようになります。

ぬえです。。
ミケだよ☆彡

そしてCatクラスからクラス変数NAMEを削除すると↓のような結果になります。

ぬえです。。
ぬえだよ☆彡

このように、同じようなclassmethodであるsayメソッドを書いても、その振る舞いはクラスの継承関係や構造によって変わります
staticmethodは完全な決め打ちで、そのものずばり静的! って感じでしたが、classmethodはこのようにstaticmethodよりも動的なメソッドです。
ここらへんがstaticmethodとの大きな違いです。

おわりに

classmethodstaticmethodも、あまり利用頻度は高くありませんが、あるといざってときに役に立つ機能と言えます。
使えるようになっておくと、より柔軟なクラス設計が可能になるでしょう。

以上、次回に続きます。

また見てね

関連動画