web-dev-qa-db-ja.com

関数内でexecを使用して変数を設定する

私はPythonを独学し始めたばかりで、このスクリプトについて少し助けが必要です。

old_string = "didnt work"   
new_string = "worked"

def function():
    exec("old_string = new_string")     
    print(old_string) 

function()

入手したいのでold_string = "worked"

26
Spacenaut

あと少しです。グローバル変数を変更しようとしているため、globalステートメントを追加する必要があります。

_old_string = "didn't work"
new_string = "worked"

def function():
    exec("global old_string; old_string = new_string")
    print(old_string)

function()
_

次のバージョンを実行すると、バージョンで何が起こったかがわかります。

_old_string = "didn't work"
new_string = "worked"

def function():
    _locals = locals()
    exec("old_string = new_string", globals(), _locals)
    print(old_string)
    print(_locals)

function()
_

出力:

_didn't work
{'old_string': 'worked'}
_

それを実行した方法では、基本的に未定義の動作であるexecの関数のローカル変数を変更しようとしました。 exec docs の警告を参照してください:

注:デフォルトのlocalsは、以下の関数locals()で説明されているように動作します:変更デフォルトのlocals辞書への変更は試みるべきではありません。関数exec()が返された後、localsに対するコードの影響を確認する必要がある場合は、明示的なlocals辞書を渡します。

および関連する警告 locals()

注:この辞書の内容は変更しないでください。変更は、インタプリタが使用するローカル変数と自由変数の値に影響しない場合があります。

13
thebjorn

execに関数内からグローバル変数を更新させる別の方法として、globals()をそれに渡すことです。

_>>> def function(command):
...    exec(command, globals())
...
>>> x = 1
>>> function('x += 1')
>>> print(x)
2
_

locals()とは異なり、globals()辞書を更新すると、常に対応するグローバル変数が更新され、逆の場合も同様です。

4
khelwood