クラス変数とインスタンス変数
class A():
hoge = 'HOGE'
def __init__(self):
self.fuga = 'FUGA'
hoge
がクラス変数で、 fuga
がインスタンス変数。
インスタンス変数を変更するには?
class A():
def __init__(self):
self.fuga = 'FUGA'
def set_fuga(self, value):
self.fuga = value
def print_fuga(self):
print(self.fuga)
a = A()
a2 = A()
a.print_fuga() # >>> FUGA
a.set_fuga('FUGA2')
# または
a.fuga = 'FUGA2'
a.print_fuga() # >>> FUGA2
a2.print_fuga() # >>> FUGA # もちろん a2 は変更されない。
クラス変数を変更するには?
class A():
hoge = 'HOGE'
def set_hoge(self, value):
A.hoge = value
@classmethod
def set_hoge2(cls, value): # クラスメソッド。
cls.hoge = value
@classmethod
def print_hoge(cls): # クラスメソッド。
print(cls.hoge)
a = A()
a2 = A()
a.print_hoge() # >>> HOGE
a.set_hoge('HOGE2')
# または
a.set_hoge2('HOGE2')
# または
A.hoge = 'HOGE2'
a.print_hoge() # >>> HOGE2
a2.print_hoge() # >>> HOGE2 # クラス変数なので a も a2 同じものを指す。
A.print_hoge() # >>> HOGE2 # print_hoge() はクラスメソッドなので初期化しなくても使える。
ちょっとキモイ仕様(Pythonのやさしさ?)
class A():
hoge = 'HOGE'
def __init__(self) -> None:
print(self.hoge) # >>> HOGE
self.hoge = 'NO_HOGE'
print(self.hoge) # >>> NO_HOGE
A()
インスタンス変数を定義していない間に限り、self
からクラス変数にアクセスできる。どうやら self
を使ってアトリビュートにアクセスしようとした時、インスタンスに無ければクラス変数からも探してくれるようだ。
class A():
hoge = 'HOGE'
def __init__(self) -> None:
self.hoge = 'NO_HOGE'
print(self.hoge) # >>> NO_HOGE
print(A.hoge) # >>> HOGE
a = A()
クラス変数が消えたわけではない。