instance.name
クラス変数を呼び出すとき、instance.nameで呼び出すが、
その呼出先には2種類ある。
name
class foo:
name1 = 'test1'
def __init__(self):
self.name2 = 'test2'
bar = foo()
print(bar.name1)
# => test1
print(bar.name2)
# => test2
この2つは同じように値を変更することができる。
bar.name1 = 'huga'
bar.name2 = 'hogehoge'
print(bar.name1)
# => huga
print(bar.name2)
# => hogehoeg
ところが、次のようにすると挙動が変わる。
print(bar.__class__.name1)
# => test1
print(bar.__class__.name2)
# => AttributeError
この原因は何か。実はクラスが持つ変数には2種類存在する。
一つは普通のクラス変数。
もう一つはクラスの基本メンバーとして存在する__dict__の変数。
name
class foo:
name1 = 'test1'
def __init__(self):
self.name2 = 'test2'
bar = foo()
print(bar.__dict__)
# => {'name2':'test2'}
bar.name1 = 'hoge'
print(bar.__dict__)
# => {'name2':'test2','name1':'hoge'}
instance.nameといった呼び出し方は優先的に__dict__[name]を表示する。
__dict__[name]が存在しなかった場合のみ、__class__.nameを呼び出す。
もしクラス変数を初期値や非変更値として使いたいなら、name1のようにself.を使わずに書くべきだろう。
また、常にクラス内で規定した値で処理を行いたいのならばself.class.nameなどとして呼び出すべきだろう。
name1のように書くメリットとして、初期値に戻せるというのもある。
name
class foo:
name1 = 'test1'
def __init__(self):
self.name2 = 'test2'
bar = foo()
print(bar.name1)
# => test1
bar.name1 = 'newname'
print(bar.name1)
# => newname
del bar.name1
print(bar.name1)
# => test1
self.nameと宣言するのは、それが変更されることを前提としていたり、変更前の値を覚えておく必要が無い時だけかもしれない。