Loki's Note

色々なことに手を出して迷子中の私のための記録

【Python】動的に変数を設定する

post-featured-image

結論、locals()かglobals()を使います。

使う機会があるのかはわかりませんが…個人的にちょっと使いたくなったので調べました。

目次

locals()とglobals()を使う

times = 3

for i in range(times):
		locals()[f'local{i}'] = i
		globals()[f'global{i}'] = i

for i in range(times):
		print(f'local{i}', locals()[f'local{i}'])
		print(f'global{i}', globals()[f'global{i}'])

# 出力
# local0 0
# global0 0
# local1 1
# global1 1
# local2 2
# global2 2
説明

locals()やglobals()にはローカル変数やグローバル変数が辞書型で入っているため、そこに対してキーを動的に設定することで変数を動的に生成することができる。

ただドキュメントで「この辞書の内容は変更してはいけません」と書かれているため、この方法はよくないのかもしれない。

参考: 組み込み関数 — Python 3.10.6 ドキュメント

上の例ではスコープが分けられていないので、locals()もglobals()も同じものを返す。

locals()の補足

ちゃんとスコープを分けてlocals()を出力してみると、そのスコープの中で使われている変数の一覧が辞書で取得できる。

def main(times: int) -> None:
		for i in range(times):
				locals()[f'local{i}'] = i
				print(f'local{i}', locals()[f'local{i}'])
		
		print(locals())

if __name__ == '__main__':
		main(3)

# 出力
# local0 0
# local1 1
# local2 2
# {'times': 3, 'i': 2, 'local0': 0, 'local1': 1, 'local2': 2}

exec()とvars()を使う方法

この他にもexec()を使って追加する方法がある。

ただ、自分のやりたかったことはうまくいかなかったため、今回は不採用。

また、値の取得だけならvars()でもlocals()と同じようにできる。

exec()とvars()のサンプル
def main(times: int) -> None:
		for i in range(times):
				exec(f'local{i} = {i}')
				print(f'local{i}', vars()[f'local{i}'])
		print(vars())

if __name__ == '__main__':
		main(3)

# 出力
# local0 0
# local1 1
# local2 2
# {'times': 3, 'i': 2, 'local0': 0, 'local1': 1, 'local2': 2}

まとめ

ローカル変数に設定する場合はlocals()、グローバル変数に設定する場合はglobals()を使って追加する。