6

この動作の適切な説明が見つかりません。

>>> def a():
...     foo = 0
...     print locals()
...     def b():
...         print locals()
...     b()

>>> a()
{'foo': 0}
{}

だが:

>>> def a():
...     foo = 0
...     print locals()
...     def b():
            foo
...         print locals()
...     b()

>>> a()
{'foo': 0}
{'foo': 0}

2番目のケースではクロージャがあることは理解していますが、実際に何があり、どのような条件下で関数を返す必要があるかについての詳細な説明が見つかりませんlocals()

4

2 に答える 2

5

fooクロージャ内でに割り当てない場合、Pythonはそれをfoo1レベル上のスコープのに解決します(そして、fooどこかを見つけるか、例外をスローするまで)。

2番目の例でfoo内に言及することにより、内のローカルに入れますが、それはの本体内に解決されます。たとえば、を割り当てると、次のように表示されます。b()foob()fooa()foo = 1b()

 {'foo': 0}
 {'foo': 1}

出力として。

于 2012-08-09T20:43:20.717 に答える
4

locals()組み込み関数は、コードオブジェクトにバインドされ、インタプリタがソースコードで名前を受け取るといっぱいになるローカルシンボルテーブルを出力します。

2番目の例では、分解すると、 b関数コードにLOAD_GLOBALfooバイトコード命令が含まれます。このLOAD_GLOBAL命令は、スコープを上に移動し、外部foo名を見つけて、クロージャーの(関数b)コードオブジェクトのco_names属性に名前オフセットを追加することにより、コードオブジェクトにバインドします。

locals()関数は、ローカルシンボルテーブルを出力します(前述のように、関数のコードオブジェクトのco_names属性)。

コードオブジェクトの詳細については、こちらをご覧ください。

于 2012-08-09T20:53:26.673 に答える