sec04 - クラス変数・クラスメソッド・スタティックメソッドの違いと使い分け【Python入門】
スポンサーリンク

クラス変数とは?全体で共有される変数の仕組み

クラス変数とは、「クラス全体で共有される値」のことです。たとえば、「Carクラスで作られたすべての車の販売台数」など、個々のインスタンスに関係なく共通するデータを管理したいときに使います。

class Car:
    # クラス変数(全体で共有される)
    total_cars = 0

    def __init__(self, name):
        # インスタンス変数(個別のデータ)
        self.name = name
        # クラス変数を1つ増やす
        Car.total_cars += 1

    def show_info(self):
        print(f'{self.name}が販売されました。')
        print(f'現在の販売台数: {Car.total_cars}')

car1 = Car('Prius')
car1.show_info()
car2 = Car('Aqua')
car2.show_info()
Priusが販売されました。
現在の販売台数: 1
Aquaが販売されました。
現在の販売台数: 2

このサンプルコードの要点は次の通りです。

  • total_cars = 0 はクラス変数で、クラス全体で共有される唯一の値です。
    • メソッドの中に記述しなければ、classブロック内のどこに記述してもクラス変数として認識されますが、通常はclass行の後に続けて記述します。
  • def __init__(self, name): はインスタンスを作るときに呼ばれる特別なメソッドです。
  • Car.total_cars += 1 によって、新しい車が作られるたびにクラス全体の販売台数が1台ずつ増えていきます。クラス変数へアクセスするには、クラス名.クラス変数の形式で記述します。

クラスメソッド(classmethod)の使い方と役割

クラス変数を操作する際によく使われるのがクラスメソッドです。クラスメソッドは、インスタンスではなく「クラス自身」に対して処理を行いたいときに使います。

@classmethodというデコレーターを使って定義し、第一引数にはclsを使います。

class Car:
    total_cars = 0

    def __init__(self, name):
        self.name = name
        Car.total_cars += 1

    @classmethod
    def show_total(cls):
        print(f'現在の販売台数: {cls.total_cars}')


car1 = Car('Prius')
car2 = Car('Aqua')
Car.show_total()  # クラスメソッドの呼び出し
現在の販売台数: 2

このサンプルコードの要点は次の通りです。

  • @classmethod
    • これは、このメソッドが『クラスメソッドである』ことをPythonに伝えるための特別な記号(デコレーター)です。
  • def show_total(cls):
    • クラスメソッドの第一引数はclsです。clsは「クラス自身」を表します。
    • インスタンス変数にアクセスするselfと似ていますが、selfは「個々のインスタンス」、clsは「クラス全体」です。
  • print(f"現在の販売台数: {cls.total_cars}")
    • クラス変数にアクセスする際、クラス名ではなくclsを使ってアクセスしています。
    • この書き方をしておくと、サブクラスを作ったときにも同じメソッドを再利用しやすくなります。
  • Car.show_total()
    • クラス名.クラスメソッド()の形式で記述することで、インスタンスを使わずに、メソッドを実行することができます。
スポンサーリンク

スタティックメソッド(staticmethod)の特徴と使い分け

スタティックメソッドは、クラスやインスタンスの情報にアクセスしない「汎用的な関数」を定義したいときに使います。たとえば文字列整形や単純な計算など、補助的な処理を記述するときに最適です。

@staticmethodというデコレーターを使って定義します。

class Car:
    total_cars = 0

    def __init__(self, name):
        self.name = name
        Car.total_cars += 1

    @staticmethod
    def show_message(greeting):
        print(f'{greeting}。Carクラスへようこそ!')


Car.show_message('こんにちは')  # こんにちは。Carクラスへようこそ!
こんにちは。Carクラスへようこそ!
  • @staticmethod
    • 「この関数はクラスにもインスタンスにも依存しないですよ」と明示するデコレーターです。
  • def show_message(greeting):
    • スタティックメソッドは、selfclsのような引数を受け取りません。呼び出し側から引数を受け取る場合は、通常の関数と同じようにパラメータの定義を行います。
  • スタティックメソッドは、クラスに関連する便利関数をまとめるときに使われます。
    • たとえば、車の名前を整形する関数や、価格をフォーマットする関数などが良い例です。
  • Car.show_message()
    • クラスから直接呼び出すことができます。インスタンスを作る必要はありません。

ファクトリーメソッド(classmethodの実用例)

ファクトリーメソッドは、通常のコンストラクタ(__init__)を使わず、データの前処理をしてからインスタンスを返すような場面で使われます。

入力データの整形や検証を行ったうえでインスタンスを生成できる柔軟な手法で、複雑な初期化処理を隠し、利用者が簡単にインスタンスを作れるようにする設計パターンとして広く使われています。

class Car:
    total_cars = 0

    def __init__(self, name):
        self.name = name
        Car.total_cars += 1

    @classmethod
    def from_string(cls, name_str):
        # 文字列を整えてから、Carインスタンスを作成するファクトリーメソッド
        name = name_str.strip().capitalize()
        return cls(name)

    @classmethod
    def show_total(cls):
        print(f'現在の販売台数: {cls.total_cars}')


car = Car.from_string(' corolla ')
print(car.name)
Car.show_total()
Corolla
現在の販売台数: 1
  • @classmethod
    • ファクトリーメソッドも、クラスメソッドとして定義します。
    • ここではclsを使って新しいインスタンス(cls(name))を作成しています。
      • cls(name)Car(name)と同義です。
  • def from_string(cls, name_str):
    • 通常の__init__ではなく、文字列データを整形してからインスタンスを作っています。
    • つまり「入力の前処理を行って、きれいな形でインスタンスを返す」ような用途に便利です。
  • 「ファクトリーメソッド」とは、
    • 「複雑な初期化手順を隠して、簡単にインスタンスを作れるようにしたメソッド」のことです。
    • 例えるなら「車の製造ラインを一本化した受付口」のようなものです。

今回のレクチャーのまとめ

クラス変数とインスタンス変数の違いを整理

項目クラス変数インスタンス変数
定義場所クラス定義の直下__init__() の中などで self.変数名 として定義
所有者クラス全体で共有各インスタンスごとに別々
アクセス方法クラス名.変数名 または self.変数名self.変数名
変更の影響範囲すべてのインスタンスに影響するそのインスタンスだけに影響する
主な用途全体で共有する情報(例:作成されたインスタンス数、共通設定など)個々のオブジェクト固有の情報(例:車の色や速度など)

たとえば「全ての車の総台数を数える」ような情報はクラス変数に適し、「各車の色や燃料量」はインスタンス変数に適しています。

関数・インスタンスメソッド・クラスメソッド・スタティックメソッドの使い分け方

種類定義場所呼び出し方第一引数インスタンスやクラスとの関係主な用途
通常の関数クラスの外部関数名()なしクラスとは無関係一般的な処理をまとめる
インスタンスメソッドクラス内インスタンス.メソッド名()selfインスタンスに属する(インスタンス変数にアクセスできる)各オブジェクトごとの動作(例:車を走らせる)
クラスメソッドクラス内(@classmethodクラス名.メソッド名() または インスタンス.メソッド名()clsクラスそのものに属する(クラス変数にアクセスできる)クラス全体で共有する操作や設定(例:インスタンス数を管理)
スタティックメソッドクラス内(@staticmethodクラス名.メソッド名() または インスタンス.メソッド名()なしインスタンスやクラスに依存しない汎用的な処理(例:入力値のチェックなど)
  • self … 「このインスタンス自身」を指す。インスタンス変数にアクセスするために使う。
  • cls … 「このクラス自身」を指す。クラス変数を操作したいときに使う。
  • @staticmethod … 「クラスの中で定義されているけれど、独立した関数」。selfcls も受け取らない。
目的向いているメソッド
個々のオブジェクトの状態を変更したいインスタンスメソッド
クラス全体で共有する情報を操作したいクラスメソッド
単なる便利関数として使いたいスタティックメソッド
スポンサーリンク