我的应用程序需要执行一些任意的 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给出的答案为我解决了这个问题,但有人可以解释为什么我们需要在 multiprocessing
的情况下传递 globals
而在正常执行的情况下为什么不需要传递?
最佳答案
当我添加 globals()
时它起作用了作为 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
import 以某种方式超出函数范围 x
(如果我将 import os
移动到 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>
关于python - 在 Multiprocessing python 中无法访问全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55024907/