結論、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()を使って追加する。