30

import ステートメントを文字列に入れ、それを実行すると、動作します (ランダムな数字を出力します):

code = """
import random
def f():
    print random.randint(0,9)
"""

def f():
    pass

exec code
f()

ここで、exec codeandf()を独自の関数に入れて呼び出すと、機能しません。

def test():
    exec code
    f()

test()

それは言いNameError: global name 'random' is not definedます。

4

3 に答える 3

26

これはどう:

def test():
    exec (code, globals())
    f()
于 2012-09-20T01:48:51.787 に答える
20

ここで何が起こっているかというと、モジュール 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ではないためです。これを行った場合:ftest

def test():
    import random
    def f():
        print random.randint(0,9)
    f()

それはうまくいくでしょう。ただし、ネストされた関数では、外側の関数をコンパイルするときに、外側の関数に内側の関数の定義が含まれている必要があります。これは、セル変数を設定して、2 つの (外側と内側の) 関数間で共有される変数を保持する必要があるためです。

グローバル名前空間にランダムに入るには、次のようにします

exec code in globals(),globals()

キーワードの後の exec への引数inは、コードが実行されるグローバルおよびローカル名前空間です (したがって、exec されたコードで定義された名前が格納される場所)。

于 2012-09-20T01:54:10.733 に答える
7

グローバルrandomモジュールが必要であることを指定します

code = """
import random
def f():
  global random
  print random.randint(0,9)
"""

ここでの問題はrandom、グローバル スコープではなく、関数スコープにモジュールをインポートしていることです。

于 2012-09-20T01:39:37.223 に答える