如何移交* args到pathos'amap

时间:2017-10-17 13:27:22

标签: python pathos

我有以下问题:我想使用来自pathos.multiprocessing的amap。

import pathos as pt

class Foo:

    def __init__(self):
        pass

    def f(self, a, b, c):
        return a + b + c

    def g(self):  
        pool = pt.multiprocessing.ProcessPool()
        def _h(a, b, c):
            k = self.f(a, b, c)
            return k/2
        result = [pool.amap(_h, (i, j, k)) for i in range(3) for j in range(5) for k in range(7)]
        return result

a = Foo()
b = a.g()
b[0].get()

虽然我可以做f内的所有事情,但必须有这两个函数f和g。

如果我运行此代码,我会得到g预期3个参数但只给出了一个。

TypeError: _h() takes exactly 3 arguments (1 given)

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

因为amap定义为:

149     def amap(self, f, *args, **kwds): # register a callback ?
...
152         return _pool.map_async(star(f), zip(*args)) # chunksize

源代码中有一个用法示例:

pool.amap(pow, [1,2,3,4], [5,6,7,8])

l作为您的输入:

l = [(i, j, k) for i in range(3) for j in range(5) for k in range(7)]

你可以改变你的意见:

results = pool.amap(_h, *map(list, zip(*l)))

或使用发电机,它应该更快:

def getter(n):
    for e in l:
        yield e[n]
result = pool.amap(_h, *[getter(n) for n in range(3)])

或者,改为使用apipe api:

results = [pool.apipe(_h, l)]

当然,一旦你明白了,你可以通过它的界面使输入更合适。但为什么不使用multiprocessing.pool.async_apply代替它,它的界面与你最初的预期完全一样。

答案 1 :(得分:0)

我知道它看起来很奇怪,但是我喜欢在悲刀中将数据传递为可迭代的想法。

要实现您所寻找的内容,您必须将元素作为单独的可迭代项目传递。这是一个例子:

pool.amap(_h, (i,),( j,),(k,))

请注意在这里传递参数的奇怪方式:def g(self): pool = pt.multiprocessing.ProcessPool() def _h(a, b, c): print('a: {0} b: {1}. c: {2}'.format(a, b, c)) k = self.f(a, b, c) return k/2 return [pool.amap(_h, (1,4), (2,5), (3,6))]

如果跟踪_pool.map_async(star(f), zip(*args))稍微调用一下,你就可以知道为什么会这样做。

通常,您可能希望使用不同的参数多次调用您的函数。以下是我为证明这一点所做的工作:

a: 1 b: 2. c: 3
a: 4 b: 5. c: 6

即使我明确地调用了一次函数,它也被执行了两次。 输出:

{{1}}

希望这有帮助。