问题描述
在代码块中直接调用时,调用导入的函数 helpers.test_func(...) 会成功。
但由于此异常而失败:
File "<string>",line 11,in <module>
File "<string>",line 8,in z
NameError: name 'helpers' is not defined
code = """
from my_proj import helpers
helpers.test_func("a")
def y():
print("b")
def z():
helpers.test_func("c")
y()
z()
"""
def test_func(v1):
print("--->{}".format(v1))
def test():
exec(code)
if __name__ == '__main__':
test()
--->a
b
File "<string>",in <module>
File "<string>",in z
NameError: name 'helpers' is not defined
为什么当调用 z 函数时 helpers 模块消失了?
我为什么要这样做?
我正在尝试实现一个工具,该工具加载函数文件 (a_file.py),其中定义了函数,并且我想从该工具调用函数。像这样:
_locals = {}
_globals = {}
eval(code_of_file,_globals,_locals)
f = _locals["func_defined_in_scope_of_file"]
f() # <---- this fails with the same NameError as above
上面的例子比较简单,如果失败了,我相信如果我能解决上面的问题,我就可以使用相同的解决方案。
不太理想的解决方法:
在函数 z 的主体中添加 from dry_pipe import helpers 解决了问题,但并不优雅
code = """
from dry_pipe import helpers
helpers.test_func("a")
def y():
print("b")
def z():
from dry_pipe import helpers
helpers.test_func("c")
y()
z()
"""
解决方法
您的范围有问题。 exec
函数在“当前”范围内运行,因此您应该将 globals()
作为第二个参数传递给 exec
函数(以查看全局属性)。我已经写了一个工作示例,请在下面查看。 ((不得不说,exec
函数真的不推荐使用))
my_proj.py:
class Helper:
@classmethod
def test_func(cls,a):
print("TEST FUNC - {}".format(a))
test.py:
code = """
from my_proj import Helper as helpers
helpers.test_func("a")
def y():
print("b")
def z():
helpers.test_func("c")
y()
z()
"""
def test_func(v1):
print("--->{}".format(v1))
def test():
exec(code,globals())
if __name__ == '__main__':
test()
输出:
>>> python3 test.py
TEST FUNC - a
b
TEST FUNC - c