一つのクラスから作った複数のインスタンスで共通の変数を使いたい(@classmethod)


概要


クラス内のコンストラクタやメソッド以外で書かれた変数を
コンストラクタや関数内で数値を変化させると
すべてのインスタンスで共通でその変化が起こる

しかし外部からアクセスした変数は
インスタンスごとにそれぞれ独立している


class aClass():
    aCount = 0

ob01 = aClass()
ob02 = aClass()

ob01.aCount = ob01.aCount + 1
ob02.aCount = ob02.aCount + 1

print(ob01.aCount)
print(ob02.aCount)
print('')

print(aClass.aCount)

aClass.aCount = aClass.aCount + 1

print(aClass.aCount)
print(ob01.aCount)
print(ob02.aCount)

aClass.aCount = aClass.aCount + 1

print(aClass.aCount)
print(ob01.aCount)
print(ob02.aCount)

print('')

class bClass():
    bCount = 0

    def __init__(self):
        bClass.bCount = bClass.bCount + 1

    def num(self):
        bClass.bCount = bClass.bCount + 1

ob03 = bClass()
ob04 = bClass()

print(ob03.bCount)
print(ob04.bCount)

ob03.num()
ob04.num()

print(ob03.bCount)
print(ob04.bCount)










1
1


0



1
1
1



2
1
1












インスタンスを作った瞬間コンストラクタで+1される
インスタンスを作った瞬間コンストラクタで+1される

2
2

+1される
+1される

4
4

出力


1
1

0
1
1
1
2
1
1 ※外部から変数を変化させても各インスタンスで変数は独立している

2
2
4
4

説明


間違えやすい問題



概要


クラス定義の時に

@classmethod

と書いてすぐ下に書いた関数の第1引数はそのクラスそのものを示す
変数をコンストラクタや関数以外で定義しておき

@classmethod直下の関数の第1引数.その変数

とするとそのクラスのすべてのインスタンスで共通の変数を作れる。
グローバル変数的なものを作れる。
この関数内で変数を変化させると
すべてのインスタンスで共通で変化する

ただし外部から変数を直接変化させたものはインスタンスごとに独立している

以下の############################で区切られた上下2つのprint結果は同じになる


class aClass():
    count = 0

    @classmethod
    def num(cls):
        cls.count = cls.count + 1

ob01 = aClass()
ob02 = aClass()

print(ob01.count)
print(ob02.count)
print('')

ob01.num()
print(ob01.count)
print(ob02.count)
print('')

aClass.num()
print(ob01.count)
print(ob02.count)
print('')

ob01.count = ob01.count + 1
print(ob01.count)
print(ob02.count)
print('')

##################################

class aClass():
    count = 0

    def num(self):
        aClass.count = aClass.count + 1

ob01 = aClass()
ob02 = aClass()

print(ob01.count)
print(ob02.count)
print('')

ob01.num()
print(ob01.count)
print(ob02.count)
print('')

aClass().num()
print(ob01.count)
print(ob02.count)
print('')

ob01.count = ob01.count + 1
print(ob01.count)
print(ob02.count)
print('')











0
0



1
1


aClassすぐ後ろに()をつけてはいけないのに注意、selfがないため
2
2



3
2













0
0



1
1


aClassすぐ後ろに()が必要なのに注意、selfがあるため
2
2



3
2

出力



説明



間違えやすい問題