我试图用我在其他函数中动态创建的函数来做一些多处理。如果发送给ProcessPoolExecutor的函数是模块级的,我似乎可以运行这些函数:
def make_func(a):
def dynamic_func(i):
return i, i**2 + a
return dynamic_func
f_dyns = [make_func(a) for a in range(10)]
def loopfunc(i):
return f_dyns[i](i)
with concurrent.futures.ProcessPoolExecutor(3) as executor:
for i,r in executor.map(loopfunc, range(10)):
print(i,":",r)
输出:
^{pr2}$但是,如果多处理是由类函数启动的,则无法执行此操作:
class Test:
def __init__(self,myfunc):
self.f = myfunc
def loopfunc(self,i):
return self.f(i)
def run(self):
with concurrent.futures.ProcessPoolExecutor(3) as executor:
for i,r in executor.map(self.loopfunc, range(10)):
print(i,":",r)
o2 = Test(make_func(1))
o2.run()
输出:
Traceback (most recent call last):
File "/home/farmer/anaconda3/envs/general/lib/python3.6/multiprocessing/queues.py", line 234, in _feed
obj = _ForkingPickler.dumps(obj)
File "/home/farmer/anaconda3/envs/general/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
AttributeError: Can't pickle local object 'make_func.<locals>.dynamic_func'
另一方面,如果不使用动态生成的函数,我可以对类函数运行多处理。有什么办法吗?我尝试将动态生成的函数添加到“globals”字典中,但似乎没有帮助:
def make_func_glob(a):
def dynamic_func(i):
return i, i**2 + a
globals()['my_func_{0}'.format(a)] = dynamic_func
make_func_glob(1)
print("test:", my_func_1(3))
o3 = Test(my_func_1)
o3.run()
输出:
test: (3, 10)
Traceback (most recent call last):
File "/home/farmer/anaconda3/envs/general/lib/python3.6/multiprocessing/queues.py", line 234, in _feed
obj = _ForkingPickler.dumps(obj)
File "/home/farmer/anaconda3/envs/general/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
AttributeError: Can't pickle local object 'make_func_glob.<locals>.dynamic_func'
所以python仍然认为它是一个本地对象,即使我把它添加到了“globals”dict中,像这样的“globals”想法就可以了,我不需要任何花哨的东西。为了方便起见,我只是动态地创建这些函数。如果它们能成为全球性的物体,我会非常高兴的。它们总是由模块定义的,其中只有一堆具有几乎相同的定义,因此以编程方式定义它们比手动编写它们更方便。所以我认为有可能让python将它们识别为“真”函数,就像我通过“exec”定义它们一样。或者至少可以在并行代码中使用它们。在
正如错误消息所示,它更多地与pickle有关,而不是动态生成的函数。来自https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor
从https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled可以提取的函数种类:
这意味着其他种类的功能不能被腌制。从问题中的代码中跳出一个不符合此函数的函数:
dynamic_func
来自。。。在…你暗示这就是问题所在。。。。在
你可以的!您可以将
^{pr2}$dynamic_func
放在顶层,并使用partial
而不是闭包。。。在所以全部。。。在
但是。。。我不知道为什么原来不上课的形式有效。根据我的理解,这可能是在试图对一个非顶级函数进行处理,所以我认为我的理解是有缺陷的。在
相关问题 更多 >
编程相关推荐