ここで何が起こっているかというと、モジュール random がテストでローカル変数としてインポートされているということです。これを試して
def test():
exec code
print globals()
print locals()
f()
印刷します
{'code': '\nimport random\ndef f():\n print random.randint(0,9)\n', '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x02958BF0>, '__name__': '__main__', '__doc__': None}
{'random': <module 'random' from 'C:\Python27\lib\random.pyc'>, 'f': <function f at 0x0295A070>}
f
見えない理由は、 --if内にネストされた関数random
ではないためです。これを行った場合:f
test
def test():
import random
def f():
print random.randint(0,9)
f()
それはうまくいくでしょう。ただし、ネストされた関数では、外側の関数をコンパイルするときに、外側の関数に内側の関数の定義が含まれている必要があります。これは、セル変数を設定して、2 つの (外側と内側の) 関数間で共有される変数を保持する必要があるためです。
グローバル名前空間にランダムに入るには、次のようにします
exec code in globals(),globals()
キーワードの後の exec への引数in
は、コードが実行されるグローバルおよびローカル名前空間です (したがって、exec されたコードで定義された名前が格納される場所)。