在Python中,为什么函数中的exec中的导入不起作用?

Ale*_*rga 24 python import function exec

我可以将一个import语句放在一个字符串中,执行它,它可以工作(打印一个随机数字):

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

def f():
    pass

exec code
f()
Run Code Online (Sandbox Code Playgroud)

现在,如果我把exec codef()自己的功能和调用它,这是行不通的.

def test():
    exec code
    f()

test()
Run Code Online (Sandbox Code Playgroud)

它说NameError: global name 'random' is not defined.知道发生了什么事吗?谢谢

jjm*_*jjm 19

这里发生的是随机模块随机导入为测试中的局部变量.试试这个

def test():
    exec code
    print globals()
    print locals()
    f()
Run Code Online (Sandbox Code Playgroud)

将打印

{'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>}
Run Code Online (Sandbox Code Playgroud)

原因是f看不到内部没有嵌套函数 - 如果你这样做了:randomftest

def test():
    import random
    def f():
        print random.randint(0,9)
    f()
Run Code Online (Sandbox Code Playgroud)

它会奏效.但是,嵌套函数要求外部函数在编译外部函数时包含内部函数的定义 - 这是因为您需要设置单元格变量来保存在两个(外部和内部)函数之间共享的变量.

要随机进入全局命名空间,您只需执行此类操作即可

exec code in globals(),globals()
Run Code Online (Sandbox Code Playgroud)

in关键字后面的exec参数是执行代码的全局和本地命名空间(因此,存储了exec'd代码中定义的名称).


Yev*_*kiy 18

这个怎么样:

def test():
    exec (code, globals())
    f()
Run Code Online (Sandbox Code Playgroud)


Aes*_*ete 6

指定你想要全局random模块

code = """
import random
def f():
  global random
  print random.randint(0,9)
"""
Run Code Online (Sandbox Code Playgroud)

这里的问题是您将random模块导入到函数作用域,而不是全局作用域。