13

以下は、Python 3 でエラーなしで実行されます。

code = """
import math

def func(x):
    return math.sin(x)

func(10)
"""
_globals = {}
exec(code, _globals)

しかし、ローカル変数 dict もキャプチャしようとすると、次のエラーで失敗しますNameError

>>> _globals, _locals = {}, {}
>>> exec(code, _globals, _locals)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-9-aeda81bf0af1> in <module>()
----> 1 exec(code, {}, {})

<string> in <module>()

<string> in func(x)

NameError: name 'math' is not defined

グローバル変数とローカル変数の両方をキャプチャしながら、このコードを実行するにはどうすればよいですか?

4

1 に答える 1

14

exec()ドキュメントから:

モジュール レベルでは、グローバルとローカルは同じ辞書であることに注意してください。globalslocalsexecとして 2 つの個別のオブジェクトを取得すると、コードはクラス定義に埋め込まれているかのように実行されます。

2 つの個別の辞書を渡しましたが、モジュール スコープのグローバルを使用できるようにする必要があるコードを実行しようとしました。import mathクラス内の はローカルスコープ属性を生成し、クラススコープ名は関数クロージャーと見なされないため、作成した関数はそれにアクセスできません。

Python 実行モデル リファレンスの名前付けとバインドを参照してください。

および へのクラス定義ブロックと引数は、名前解決のコンテキストでは特別ですexec()eval()クラス定義は、名前を使用および定義できる実行可能なステートメントです。これらの参照は、バインドされていないローカル変数がグローバル名前空間で検索されることを除いて、名前解決の通常の規則に従います。クラス定義の名前空間は、クラスの属性辞書になります。クラス ブロックで定義される名前のスコープは、クラス ブロックに限定されます。メソッドのコードブロックには及ばない[.]

クラス定義でコードを実行しようとすると、エラーを再現できます。

>>> class Demo:
...     import math
...     def func(x):
...         return math.sin(x)
...     func(10)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in Demo
  File "<stdin>", line 4, in func
NameError: name 'math' is not defined

1 つの辞書を渡すだけです。

于 2016-09-22T19:44:01.970 に答える