locals()["x"] = 1は意味が無い
locals()["x"] = 1
locals()を変更すると変数を無理矢理定義できる!
というのをどこかで見た記憶がありますが、それはウソです。
ドキュメントを見てもlocals()の変更は意味がありません。
locals()
現在のローカルシンボルテーブルを表す辞書を更新して返します。 警告: この辞書の内容は変更してはいけません; 値を変更しても、インタプリタが使うローカル変数の値には影響しません。
このコードを実行してみると分かります。
from __future__ import division, print_function, unicode_literals # globals() はいじれる globals()["x0"] = 0 print(x0) # => 0 # locals() もいじれる locals()["x1"] = 1 print(x1) # => 1 def spam(): # globals() はいじれる globals()["x2"] = 2 print(x2) # => 0 # locals() はいじれない locals()["x3"] = 3 print(x3) # => NameErrorが発生 spam()
globals()はいじれるようですが、関数の中のlocals()はいじれません。
グローバルスコープではlocals()もいじれていますが、それはglobals()とlocals()がグローバルスコープでは同じ辞書だからです。
from __future__ import division, print_function, unicode_literals print(locals() is globals()) # => True def spam(): print(locals() is globals()) # => False spam()
しかしながら、ローカル変数を好き勝手に定義したい事はたまによくあります。
テンプレートエンジンを作る時とか。
そんなときにはexec文を使えば良いでしょう。
from __future__ import division, print_function, unicode_literals def spam(): adict = {"x": 1, "y":2, "z":3} for k, v in adict.items(): exec "{0} = v".format(k) print(x, y, z) # => 1 2 3 spam()