【问题标题】:Argument order with python functools partialpython functools partial的参数顺序
【发布时间】:2016-01-23 00:17:49
【问题描述】:

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

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

我有什么选择(除了明显的改变原始功能)?

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()

【问题讨论】:

    标签: python multiprocessing functools


    【解决方案1】:

    顺序很重要,因为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()
    

    【讨论】:

    • 我不能只用 f2 之类的东西硬编码参数。这些值直到运行时才知道。我将编辑我的问题以使其更清楚。另外我仍然不明白为什么参数顺序会导致此错误。谢谢
    • @user2133814,对不起,我的意思是调用f(i, s1='a', s2='c') 而不是func(i, s1='a', s2='b')。换句话说,partial 返回一个带有 3 个参数的可调用对象,其中 2 个现在具有默认值。
    猜你喜欢
    • 2013-02-26
    • 2021-08-24
    • 2011-05-21
    • 2016-12-20
    • 2013-06-27
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 2013-07-02
    相关资源
    最近更新 更多