我正在Windows 10计算机上通过Spyder 3.6.5在Python 3.6中使用multiprocessing.Pool。目的是通过导入多个输入来从简单的平方函数中获得输出(在此示例中,针对实际问题仅包含4个值)。下面的代码可以正常工作:
import numpy as np
import multiprocessing
from multiprocessing import Pool
data=[]
data.append(np.array([1,2]))
data.append(np.array([4,5]))
Output=np.zeros((2,2))
for i in range (0,2):
data1=data[i]
def square(x):
return x*x
if __name__ == '__main__':
__spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)"
with Pool(multiprocessing.cpu_count()) as p:
output = p.map(square, data1, chunksize=10)
p.close()
output=np.asarray(output)
Output[i]=output
当我想将输入平方函数值(x)指定为:
def square(ii):
x=data1[ii]
return x*x
for循环运行两次(由于'for i在(0,2)范围内'),但是p.map的结果在每次运行中都相同,并且等于第二次运行,即不是输出= np.array([[1,4],[16,25]])我得到Output = np.array([[16,25],[16,25]])。似乎for循环在i = 1的情况下运行了两次,而不是在第一个循环i = 0和在第二个循环i = 1中运行。
关于我在做什么错的任何想法?
答案 0 :(得分:0)
Python中的闭包不会复制它们关闭的变量的值。他们只是引用该范围。在您的第二次尝试中,square
函数正在访问data1
,就好像两次迭代中的值都是不同的一样,但实际上它是对相同基础变量的引用。在多处理模块启动一个新进程并调用square
时,该变量已经更改。
例如尝试一下:
res = []
for i in range(5):
def square():
return i * i
res.append(square)
print([f() for f in res])
对于解决方案,您可以在每次迭代中手动创建一个具有适当值的新范围。
函数调用会创建一个新的作用域,因此您可以在循环外定义这样的辅助函数
def square_creater(data1):
def square(ii):
x = data1[ii]
return x * x
return square
然后在每次迭代中使用
square = square_creater(data1)
这应该有效。