0

このテスト コードではexec(Python 3.4 を使用):

vals = {}
exec('def fun(): print("Hello from fun")', vals)
exec('def main(): fun()', vals)
vals['main']()

出力は次のとおりです。

楽しみからこんにちは

しかし、これがうまくいくとは思っていませんでした。なぜなら、とが への参照を解決するための共通の名前空間を持たない別のコード片として解釈されるfunと仮定したからです。mainmainfun

では、 の実行はどのようmainに への参照を解決できるのfunでしょうか?


追加ベースの問題の理解。forとprintを使用すると、2 つの関数が同じグローバルを参照することが明らかになります。idvalsglobals

vals = {}
print('id(vals):', id(vals))
exec('def fun(): print("fun id(globals()):", id(globals())); print("Hello from fun")', vals)
exec('def main(): print("main id(globals()):", id(globals())); fun()', vals)
vals['main']()

これにより、次のことが得られます。

id(値): 32271016

メイン ID (グローバル ()): 32271016

楽しい id (グローバル ()): 32271016

楽しみからこんにちは

したがって、valsは のコードのグローバルとして使用され、exec@Dunes やその他のコメントで説明されているように、接続を提供します。ありがとう。

4

1 に答える 1

3

vals両方の関数に提供することexecで、共通の名前空間を提供したことになります。の 2 番目の引数execは、実行されるすべてのコードでグローバル参照に使用する辞書です。最初のステートメントが実行されると、ステートメントが作成さfunれ、グローバル名前空間 ( ) に格納されますvals。したがって、 whenmainを検索しようとするとfun、それがローカル変数ではないことがわかり、funそのグローバル (これも ですvals) を検索しようとします。ルックアップ機能にfun存在するため、関数が取得されて呼び出されます。それぞれに独自のものvalsを与えた場合、これは機能しません。指定しない場合は、呼び出された現在のグローバルがグローバルとして使用されます (したがって、これは引き続き機能します)。execdictvalsexec

于 2015-02-27T12:55:55.160 に答える