我的应用程序需要执行一些任意的python代码作为输入。
当我尝试使用Multiprocessing模块在不同的过程中执行它时,代码globals()
会出现一些问题。
请考虑以下可正常工作的代码。
src = """import os
def x():
print(os.getcwd())"""
exec (src)
eval('x()')
此代码可以正常工作,没有任何错误。
当我想通过以下代码通过多处理执行同一件事时,它给我一个错误,即找不到os
?
from concurrent.futures import ProcessPoolExecutor
pool = ProcessPoolExecutor(max_workers=1)
src = """import os
def x():
print(os.getcwd())"""
def my_eval(source):
try:
exec (source)
eval('x()')
except Exception as ex:
print(ex)
pool.submit(my_eval, src)
在这种情况下的输出是
<Future at 0x7fcc4c160f28 state=running>
name 'os' is not defined
viethtran给出的答案为我解决了这个问题,但是有人可以解释为什么在globals
的情况下我们需要通过multiprocessing
在正常执行的情况下为什么不通过?
答案 0 :(得分:0)
当我将exec()
添加为from concurrent.futures import ProcessPoolExecutor
pool = ProcessPoolExecutor(max_workers=1)
src = """import os
def x():
print(os.getcwd())"""
def my_eval(source):
try:
exec (source, globals())
eval('x()')
except Exception as ex:
print(ex)
pool.submit(my_eval, src)
函数的参数时,它可以工作。
name 'os' is not defined
更新:
我发现您的报告os
的原因是x
的导入在某种程度上超出了函数import os
的范围(如果我移动{{1 }}放在x
函数中),所以我决定添加globals()
作为参数,以便exec()
可以将os
导入添加到globals()
中并对其进行访问当x
调用eval()
函数时。
如果在globals()
之前和之后打印exec (source, globals())
,您会注意到模块os
和函数x
将被添加到globals()字典中。
from concurrent.futures import ProcessPoolExecutor
pool = ProcessPoolExecutor(max_workers=1)
src = """import os
def x():
print(os.getcwd())"""
def my_eval(source):
try:
print('==========')
print(globals())
print('==========')
exec(source, globals())
print('++++++++++')
print(globals())
print('++++++++++')
eval('x()')
except Exception as ex:
print(ex)
pool.submit(my_eval, src)
此代码将打印出如下内容:
==========
{'my_eval': <function my_eval at 0x7ff63c7baaa0>, 'ProcessPoolExecutor': <class 'concurrent.futures.process.ProcessPoolExecutor'>, 'src': 'import os\ndef x():\n print(os.getcwd())', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test.py', '__package__': None, '__name__': '__main__', '__doc__': None, 'pool': <concurrent.futures.process.ProcessPoolExecutor object at 0x7ff640c14050>}
==========
++++++++++
{'my_eval': <function my_eval at 0x7ff63c7baaa0>, 'ProcessPoolExecutor': <class 'concurrent.futures.process.ProcessPoolExecutor'>, 'src': 'import os\ndef x():\n print(os.getcwd())', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test.py', '__package__': None, 'x': <function x at 0x7ff63c7bac80>, '__name__': '__main__', 'os': <module 'os' from '/home/viet/anaconda2/lib/python2.7/os.pyc'>, '__doc__': None, 'pool': <concurrent.futures.process.ProcessPoolExecutor object at 0x7ff640c14050>}
++++++++++
<your pwd here>