【Python】classmethod(クラス・メソッド)の書き方【入門第37回】
目次
classmethod(クラス・メソッド)とは?
こんにちは、narupoです。
今回もクラスの機能ですが、classmethod(クラス・メソッド)という機能をご紹介します。
このclassmethod
はstaticmethod
の進化版みたいなやつです。
扱えるようになると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()
↑のようにclassmethod
はstaticmethod
のようにクラスをインスタンス化しなくても呼び出すことができます。
↑のコードの実行結果は↓のようになります。
<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'>
↑のクラスCat
はAnimal
を継承したクラスです。
↑のようにCat
のsay
メソッドの第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
との大きな違いです。
おわりに
classmethod
もstaticmethod
も、あまり利用頻度は高くありませんが、あるといざってときに役に立つ機能と言えます。
使えるようになっておくと、より柔軟なクラス設計が可能になるでしょう。
以上、次回に続きます。
また見てね