7

次の Python 2.X のコードは、ご想像のとおり "a : 2" を出力します。

def f():
  #a = 1
  exec "a = 2" in globals(), locals()
  for k,v in locals().items(): print k,":",v
  #a = 3

f()

しかし、「a = 1」のコメントを外すと、予想していなかったように「a : 1」と出力されます。さらに奇妙なことに、「a = 3」の行のコメントを外すと、何も出力されません。

答えは locals() と globals() のドキュメント、またはこのような他の質問に埋もれていると思いますが、この症状を呼び出す価値があると思いました.

ここで Python インタープリターが何を考えているか、および回避策の提案を知りたいです。

4

2 に答える 2

2

古い Python 2 ではexec、ローカルとグローバルの両方の名前空間を検索するようにバイトコードが変更されていました。

a = 2をグローバルに定義すると、これはa = 1がコメントされたときに見つかるものです。コメントを外すa = 3と、これはa「見つかった」がまだ定義されていません。

Eli Bendersky によるこの素晴らしい記事でシンボル テーブルがどのように処理されるかを読むと、ローカル変数がどのように処理されるかをよりよく理解できます。

この種のコードには使用execしないでください (これが製品コードでないことを願っています)。また、コードを Py3k に移植すると壊れます。

Python 3 のexec関数はもはやステートメントではないため、配置されている環境を変更することはできません。


おそらく私はポイントに直接行くべきです:

この動的な名前付けをすべて行う場合は、辞書を使用する必要があります。

def f():
    data = {'a': 1}
    data['a'] = 2
    if ...:
        data['a'] = 3
于 2012-09-18T20:50:57.037 に答える
1

locals関数ドキュメントから:

注:このディクショナリの内容は変更しないでください。変更は、インタープリターによって使用されるローカルおよびフリー変数の値に影響しない場合があります。

チェック中:

>>> def f():
    a = 1
    print(locals())
    locals()['a']=2
    print(a,locals())


>>> f()
{'a': 1}
1 {'a': 1}

locals()したがって、関数を介してローカルコンテキストを変更することはできません

于 2012-09-18T20:55:24.010 に答える