インスタンスを何度作り直しても __init__() で作ってるつもりの変数が変わらず、何ヶ月もハマってた
結論
python書き始めてからずーーっと勘違いしてました
class H:
val = 1 <-------これは
def __init__(self):
self.val = 1 <-------これと同じものだと思ってました
本当はこうだった
class H:
val = 1 <-------クラス変数
def __init__(self):
self.val = 1 <-------インスタンス変数
test code
import datetime, time
# クラス変数
class A:
t = datetime.datetime.today() #<-----------------# クラス変数: 何度インスタンスを作っても変わらない!!
class B:
def __new__(cls): # <----------------# __new__ インスタンス変数
self = object.__new__(cls)
# print('__new__ :', str(id(self)))
self.t = datetime.datetime.today()
return self
class C:
def __init__(self): # <----------------# __init__ インスタンス変数
self.t = datetime.datetime.today()
class D:
def __call__(self): # <----------------# __call__ インスタンス変数は class名() で呼ばれる。instance.__call__() を省力する感じ。
return datetime.datetime.today()
def start():
print("-start")
print(datetime.datetime.today())
print("-A")
instance = A()
print(A.t) # class変数のみインスタンスではなく、クラス直で呼び出せる
print(instance.t) # インスタンスから取得 <----------- 違うインスタンスでも共通の値(一番最初にclassが呼ばれたときの数字で固定
print("-B")
instance = B()
print(instance.t)
print("-C")
instance = C()
print(instance.t)
print("-D")
instance = D()
print(instance()) # <---------------- __call__ はclass名() で呼ばれる。instance.__call__() を省力する感じ。
##############################################################
if __name__ == "__main__":
start()
print("=========================================")
time.sleep(1)
start()
result
インスタンスを作り直しているのに、
-start
2020-01-30 14:29:24.227419
-A
2020-01-30 14:29:24.227217 <-----------ここと
2020-01-30 14:29:24.227217
-B
2020-01-30 14:29:24.227470
-C
2020-01-30 14:29:24.227494
-D
2020-01-30 14:29:24.227516
=========================================
-start
2020-01-30 14:29:25.230648
-A
2020-01-30 14:29:24.227217 <-----------ここが同じ orz
2020-01-30 14:29:24.227217
-B
2020-01-30 14:29:25.230766
-C
2020-01-30 14:29:25.230833
-D
2020-01-30 14:29:25.230877
他のは違う。class変数ってそういうやつやったんや・・・
全力で踏み抜くスタイル
クラス変数の使用上の注意
クラス変数にアクセスする場合は、特別な理由がない限り「インスタンス.クラス変数」や「self.クラス変数」のようにアクセスすることは避けるべきです。Python ではインスタンス変数をインスタンスオブジェクトから生成することができ、意図せずクラス変数をインスタンス変数で隠蔽してしまうことがあります。
https://uxmilk.jp/41600
色んな所で思いっきりやっております。ほえ〜。まいったまいった・・・。
まとめ
雰囲気でpythonするのはやめよう