クラスメソッドとスタティックメソッド

Pythonのクラスには前のページで学習したインスタンスメソッド以外にクラスメソッドとスタティックメソッドというメソッドがあります。

クラスメソッド

クラスメソッドはメソッド内で「クラス自身」を参照することができるメソッドです。メソッドの第1引数にはそのクラス自身をclsという名前で指定します。第2引数以降は通常の引数となります。クラスメソッドを利用するには組込みのデコレータである@classmethodを利用します。また、クラスメソッドを呼び出す場合は以下の通りクラス名とクラスメソッドをドットでつなぎます。

クラスメソッドの呼び出し
クラス名.クラスメソッド(引数)

それではサンプルです。

class Coordinate:
    """ 座標クラス """

    def __init__(self, x, y):
        """ 初期化 """
        self.x = x
        self.y = y

    def show_coordinate(self):
        """ 座標を表示する """
        print(self.x, self.y)

    @classmethod
    def create_origin(cls):
        """ Coodinateオブジェクトを生成して返す """
        origin = cls(0, 0)  # 原点の座標を生成して返す
        return origin


# クラスからクラスメソッドを使用する
cood = Coordinate.create_origin()
print(cood.show_coordinate())

# オブジェクトを生成してクラスメソッドを使用する
cood2 = cood(10, 20)
cood3 = cood2.create_origin()
print(cood3.show_coordinate())

上のコードは平面座標を表すCoordinateというクラスを実装しています。初期化時にx, y座標をしていしますが、それとは別に13行目~17行目で実装したcreate_originというクラスメソッドを使用すると原点座標を得ることができます。create_originでは引数にclsがあるため、これを利用しています。また、20行目以降で実装したクラスメソッドを呼び出しています。また、クラス変数と同様クラスメソッドはインスタンス化したオブジェクトからもアクセスすることが可能です。(24行目以降)

スタティックメソッド

スタティックメソッドはクラスに属しますが、そのクラスに依存しなメソッドです。つまり、スタティックメソッドはメンバにアクセスすることができません。また、このことから引数のselfやclsは不要となります。スタティックメソッドを実行する際は、クラス名.スタティックメソッド名で記述します。クラスメソッドを利用するには組込みのデコレータである@staticmethodを利用します。

import math

class Coordinate:
    """ 座標クラス """
 
    def __init__(self):
        """ 初期化 """
        self.x = 0 
        self.y = 0 
 
    def show_coordinate(self):
        """ 座標を表示する """
        print(self.x, self.y)

    @staticmethod
    def calc_dist(cood1, cood2):
        """ 座標間の距離を計算します """
        x = cood1.x - cood2.x
        y = cood1.y - cood2.y
        return math.sqrt((math.pow(x, 2) + math.pow(y, 2)))


cood1 = Coordinate() # インスタンスを生成する
cood1.x, cood1.y = 100, 100 

cood2 = Coordinate() # インスタンスを生成する
cood2.x, cood2.y = 200, 200 

dist = Coordinate.calc_dist(cood1, cood2) # スタティックメソッドを実行
print(dist)

例えば上のサンプルでは、座標クラスに座標間の距離を計算するメソッドを実装していますが、オブジェクトの状態に依存する機能ではないため、スタティックメソッドとして実装されています。このように、スタティックメソッドの挙動としてはクラスに属さないただの関数と同じなのですが、なんらかの方針で関数をクラスに属させたい場合に使用します。