【Python】複数のクラスで変数を共有する(クラス変数)

Pythonで複数のクラスで変数を共有するプログラムについて解説します。

複数のクラスで変数を共有する(クラス変数)

コード例

# 識別番号付きフルーツクラス

class Fruit:
    """フルーツクラス"""

    __counter = 0 # 何番までの識別番号を与えたか

    def __init__(self, name: str) -> None:
        """コンストラクタ"""
        self.__name = name
        Fruit.__counter += 1
        self.__id = Fruit.__counter

    def id(self) -> int:
        """識別番号を取得"""
        return self.__id

    @classmethod
    def max_id(cls) -> int:
        """現時点で何番までの識別番号を与えたか"""
        return cls.__counter

    def print(self) -> None:
        """データ表示"""
        print(f'{self.__name}:{self.__id}番')


apple  = Fruit('りんご')   # 識別番号は1
banana = Fruit('バナナ')   # 識別番号は2
orange = Fruit('オレンジ') # 識別番号は3

print(f'apple.id()  = {apple.id()}')
print(f'banana.id() = {banana.id()}')
print(f'orange.id() = {orange.id()}')

print(f'Fruit.max_id() = {Fruit.max_id()}')
print(f'apple.max_id() = {apple.max_id()}')

実行結果

apple.id()  = 1
banana.id() = 2
orange.id() = 3
Fruit.max_id() = 3
apple.max_id() = 3

クラス変数

このプログラムではクラスFruitを作成しています。

このクラスのインスタンスには1、2、3、…といった感じで識別番号が自動的に与えられるようになっています。

各インスタンスには1、2、3、…という識別番号がインスタンス変数として持っています。

それとは別に「現時点で何番までの識別番号を与えたのか」を表す変数が1つだけ必要になってきます。

この変数が__counterでクラス変数です。

クラス変数とインスタンス変数

このクラス変数__counterには何番までの識別番号を与えたのかを表すものです。

これはクラスFruitのインスタンスで共有すべきものです。

クラス変数はクラスに所属するものの、個々のインスタンスには所属しないデータ属性です。

クラス変数__counterは「self.」の付かない単純名で定義しています。

生成時は0が最初に一度だけ代入され、インスタンスが生成されると1ずつ増えていきます。

次に2つのメソッドを見ていきます。

コンストラクタ__init__

コンストラクタ内ではクラス変数を「クラス名.変数名」でアクセスします。

「Fruit.__counter += 1」でインクリメントした後で、インスタンス変数self.__idに代入します。

そのためインスタンスの識別番号self.__idは1、2、3、…となります。

メソッドprint

メソッドprintでは、インスタンス変数の名前self.__nameと、識別番号の値self.__idを表示します。

ここではクラス変数にはアクセスしません。

クラスメソッド

メソッドidとmax_idを見ていきます。

クラスメソッドとインスタンスメソッド

メソッドid

このメソッドでは、識別番号を取得します。

このプログラムであればappleであれば1、bananaであれば2、orangeであれば3。

このような個々のインスタンスに所属するメソッドをインスタンスメソッドといいます。

インスタンスメソッドの第1引数selfは自身のインスタンスを参照する変数です。

メソッドidでは自身のインスタンスの識別番号の値をself.__idで取り出して返却します。

呼び出し方は「インスタンス名.メソッド名(実引数の並び)」です。

このプログラムの場合だとapple.id()、banana.id()、orange.id()となります。

メソッドmax_id

このメソッドでは、現時点で何番までの識別番号を与えたのかを調べます。

このような個々のインスタンスには所属せず、クラスに所属するメソッドをクラスメソッドといいます。

クラスメソッドの前には@classmethodデコレータを前置きしています。

クラスメソッドが受け取る第1引数clsは自身が所属するクラスオブジェクトを参照する変数です。

そのためクラス変数Fruit.__counterをcls.__counterでアクセスしています。

次にクラスメソッドの呼び出し方について見ていきます。

クラスメソッドの呼び出し方

クラスメソッドは「クラス名.メソッド名(実引数の並び)」で呼び出します。

このプログラムの場合だとFruit.max_id()です。

ただ「みんなのmax_id」は「appleのmax_id」や「bananaのmax_id」や「orangeのmax_id」とも言えなくもないです。

そのためクラスメソッドは「インスタンス名.メソッド名(実引数の並び)」でも呼び出せます。

このプログラムでもapple.max_id()を表示させてFruit.max_id()と同じ値になることがわかります。

ただし紛らわしいため、一般的には前者のクラス名を使った呼び出し方を使います。

Python

Posted by ほりえりお