这个问题与SO上的these other帖子有关,但是其中建议的解决方案似乎不适用于我的情况。简而言之,我的问题可以通过以下示例进行说明。我有一个Algebra
类,其中的方法triPower
旨在为固定(a+b+c)**n
的许多n
值计算三项式的幂,即a, b, c
。为此,我想创建一个方法_triPower(a,b,c,n)
并通过pool.map()
将其传递给我的functools.partial(_triPower,...)
函数,在此我修复a, b, c
并保留n
为唯一方法参数,因为我使用的是Python 2.7,并且map
模块的multiprocessing
只需要一个参数函数(否则请参阅this post)。代码如下:
from __future__ import division
import numpy as np
import functools as fntls
import multiprocessing as mp
import multiprocessing.pool as mppl
# A couple of classes introduced to allow multiple processes to have their own daemons (parallelization)
class NoDaemonProcess(mp.Process):
# make 'daemon' attribute always return False
def _get_daemon(self):
return False
def _set_daemon(self, value):
pass
daemon = property(_get_daemon, _set_daemon)
# We sub-class multiprocessing.pool.Pool instead of multiprocessing.Pool
# because the latter is only a wrapper function, not a proper class.
class MyPool(mppl.Pool):
Process = NoDaemonProcess
# Sample class where I want a method to run a parallel loop
class Algebra(object):
def __init__(self,offset):
self.offset = offset
def trinomial(self,a,b,c):
return a+b+c
def _triPower(self,a,b,c,n):
"""This is the method that I want to run in parallel from the next method"""
return self.offset + self.trinomial(a,b,c)**n
def triPower(self,n):
pls = MyPool(4)
vals = pls.map(fntls.partial(self._triPower,a=1.,b=0.,c=1.),n)
print vals
# Testing
if __name__ == "__main__":
A = Algebra(0.)
A.triPower(np.arange(0.,10.,0.01))
以上操作无效,并产生错误(如this post所预期):
cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
因此,在同一篇文章之后,我尝试将_triPower
定义为全局函数,即
def _triPower(alg,a,b,c,n):
"""This is the method that I want to run in parallel from the next method"""
return alg.trinomial(a,b,c)**n
,然后根据以下条件编辑Algebra.triPower(...)
:
def triPower(self,n):
pls = MyPool(4)
vals = pls.map(fntls.partial(_triPower, alg=self, a=1., b=0., c=1.), n)
print vals
而后者却给出了一些奇怪的TypeError,例如:
TypeError: _triPower() got multiple values for keyword argument 'alg'
另一方面,关于尝试使方法像VeryPicklableObject中那样由this other post进行序列化的建议似乎也行不通,并且该软件包目前已失效(截至05/2019)。那么我在做错什么,如何使我的计算并行运行?