95309


以下のソースコードで、クラスの先頭で宣言した変数がvarsによって取得できません。  
`__init__`, `__str__` メソッドにおいて、vars(self)で得られる変数は、`__init__` で宣言した変数 a0, a1,
... のみです。  
デバッガにで、ブレイクポイントで停止し、selfメンバーをウォッチすると、先頭で宣言した、b0,b1,....が存在することが分かりました。  
クラスのインスタンスからメンバー変数b1を出力すると、正常に出力しています。

これはなぜでしょうか？  
`__str__` で self.b0, self.b1 ... をvarsで抜き出したいのですが、できないのでしょうか？

[code]

    import json
    
    class A():
        for i in range(32):
            exec(f"b{i} = {i}")
    
        def __init__(self):
            for i in range(32):
                exec(f"self.a{i} = {i}")
            print("__init__",vars(self)) #　ここでブレイクポイントを設定
    
        def __str__(self):
            vs = vars(self)
            return json.dumps(vs) #　ここでブレイクポイントを設定
    
    
    a = A()
    print(a)
    print(a.b1)
    
    
[/code]

出力結果

[code]

    __init__ {'a0': 0, 'a1': 1, 'a2': 2, 'a3': 3, 'a4': 4, 'a5': 5, 'a6': 6, 'a7': 7, 'a8': 8, 'a9': 9, 'a10': 10, 'a11': 11, 'a12': 12, 'a13': 13, 'a14': 14, 'a15': 15, 'a16': 16, 'a17': 17, 'a18': 18, 'a19': 19, 'a20': 20, 'a21': 21, 'a22': 22, 'a23': 23, 'a24': 24, 'a25': 25, 'a26': 26, 'a27': 27, 'a28': 28, 'a29': 29, 'a30': 30, 'a31': 31}
    {"a0": 0, "a1": 1, "a2": 2, "a3": 3, "a4": 4, "a5": 5, "a6": 6, "a7": 7, "a8": 8, "a9": 9, "a10": 10, "a11": 11, "a12": 12, "a13": 13, "a14": 14, "a15": 15, "a16": 16, "a17": 17, "a18": 18, "a19": 19, "a20": 20, "a21": 21, "a22": 22, "a23": 23, "a24": 24, "a25": 25, "a26": 26, "a27": 27, "a28": 28, "a29": 29, "a30": 30, "a31": 31}
    1
    
[/code]


CC BY-SA 4.0
2023-06-20T06:32:42.950
95306
2023-06-20T11:39:16.697
2023-06-20T08:18:10.370
3060
32891
question
python python3
selfメンバー変数がvarsで取得できないのはなぜでしょうか？


コメントの通り、class宣言の下で直接定義された変数は[クラス変数](https://aiacademy.jp/media/?p=922)として扱われます。  
そのため、`b0`...変数は`vars(A)`で取得することができます。

[code]

    import json
    
    class A():
        c1 = "クラス変数" 
        for i in range(3):
            exec(f"b{i} = {i}")
    
        def __init__(self):
            self.i1 = "インスタンス変数" 
    
        def __str__(self):
            bs = {x:vars(A)[x] for x in vars(A) if x.startswith("b")}
            return json.dumps(bs)
    
    a = A()
    print(vars(a)) # {'i1': 'インスタンス変数'}
    print(vars(A)) # {'__module__': '__main__', 'c1': 'クラス変数', 'i': 2, 'b0': 0, 'b1': 1, 'b2': 2, '__init__': <function A.__init__ at 0x...
    print(a)       # {"b0": 0, "b1": 1, "b2": 2}
    print(a.b1)    # 1
    print(A.c1)    # クラス変数
    
[/code]


CC BY-SA 4.0
2023-06-20T07:22:05.023
95309
2023-06-20T11:39:16.697
2023-06-20T11:39:16.697
9820
9820
95306
answer