您在程序中没有做“完全相同”的事情。将该确切代码逐字复制到文件中并作为 Python 脚本运行,效果很好(尽管没有可见的结果)。
我认为你实际上可能在做的是这样的:
def import_stuff():
exec("import random")
def do_stuff():
import_stuff()
exec("def f():\n\treturn random.randint(0, 10), random.randint(0, 10)")
locals()['f']()
do_stuff()
上面的代码确实会导致NameError
您的问题中指出了例外,因为(引用docs https://docs.python.org/3/library/functions.html#exec),
在所有情况下,如果省略可选部分,则代码将在当前范围内执行。
由于上面的代码导入random
纳入本地范围import_stuff()
,它不可见do_stuff()
.
事实上,上面的代码在行为上与以下代码相同:
def import_stuff():
import random
def do_stuff():
import_stuff()
def f():
return random.randint(0, 10), random.randint(0, 10)
f()
do_stuff()
……出于同样的原因,这也失败了。
假设这是您的真实代码中实际发生的情况,则通过添加修改了您的问题中的版本globals(), globals()
论点exec()
会起作用,因为这样你就显式导入了random
进入全局范围,一切都可以看到它。