参数顺序与 python functools 部分



我正在尝试将多处理与pool.map一起使用来加速函数的执行,但可迭代对象不是该函数的第一个参数。 Lambda 不起作用,因为它们不可腌制。 我尝试使用functools.partial创建一个新功能,但它失败并出现TypeError. 下面是一个非常简单的示例,具有相同的结果。 如果我将参数顺序切换为 f(i, s1, s2) ,它会按预期工作。

为什么参数顺序在这里很重要? 当我阅读文档时,这对我来说并不明显。

我有哪些选择(除了明显的更改原始功能)?

import multiprocessing
from functools import partial

def f(s1, s2, i):
    return [s1] + [s2]*i
def main():
    # other code... constants for f aren't known until runtime
    pool = multiprocessing.Pool()
    func = partial(f, s1='a', s2='c')
    for strings in pool.map(func, range(10)):
        print(strings)
    pool.close()
    pool.join()
if __name__ == '__main__':
    main()

更新:我能想到的最好的是在模块级别创建一个包装器来切换参数顺序,然后从包装器中创建一个部分。 看起来一点也不漂亮,看起来一点也不蟒蛇。

import multiprocessing
from functools import partial

def f(s1, s2, i):
    return [s1] + [s2]*i
def wrapper(i, s1, s2):
    return f(s1, s2, i)
def main():
    # other code... constants for f aren't known until runtime
    pool = multiprocessing.Pool()
    func = partial(wrapper, s1='foo', s2='bar')
    for strings in pool.map(func, range(10)):
        print(strings)
    pool.close()
    pool.join()
if __name__ == '__main__':
    main()

顺序很重要,因为pool.map正在调用f(i, s1='a', s2='c')。你可以这样写你的部分:

import multiprocessing
def f(s1, s2, i):
    return [s1] + [s2]*i
def f2(i):
    return f('a','c',i)
if __name__ == '__main__':
    pool = multiprocessing.Pool()
    for strings in pool.map(f2, range(10)):
        print(strings)
    pool.close()
    pool.join()

如果您使用的是 python3.3,您可以使用pool.starmap

import multiprocessing
from itertools import repeat
def f(s1, s2, i):
    return [s1] + [s2]*i
if __name__ == '__main__':
    pool = multiprocessing.Pool()
    for strings in pool.starmap(f, zip(repeat('a'), repeat('c'), range(10))):
        print(strings)
    pool.close()
    pool.join()

最新更新