Python多进程处理多参数函数的4种方案

何川
何川
发布时间:2026-10-13 | 4人浏览过
原创

本文探讨Python中multiprocessing库处理含多个参数的函数时的常见困境及解决方案。通过对比偏函数partial、可变参数包装、pathos库及内置starmap四种方法,详细解析各自实现原理与优缺点。推荐优先使用starmap,因其无需额外依赖且支持任意数量参数,适合高效并行计算场景。

问题引出

1. 问题引出

在实际开发中,程序运行效率至关重要,追求更快的执行速度是常态。针对Python语言,通常借助multiprocessing库来实现多进程并行处理,例如以下基础示例:

假设存在一个名为my_print的函数,其功能仅为打印传入的参数:

def my_print(x): print(x)

若觉得单进程执行速度无法满足需求,可尝试将其改造为多进程模式:


from multiprocessing import Pool
 
def my_print(x):
  print(x)
 
if __name__ == "__main__":
  x = [1, 2, 3, 4, 5]
  pool = Pool()
  pool.map(my_print, x)
  pool.close()
  pool.join()

上述方式在单参数场景下能显著提升速度,但若函数参数不止一个x,而是包含多个参数,直接套用上述代码是否可行?例如,my_print函数新增参数y:

def my_print(x, y): print(x + y)

查阅Pool类中map方法的文档说明:


def map(self, func, iterable, chunksize=None):
  '''
  Apply `func` to each element in `iterable`, collecting the results
  in a list that is returned.
  '''
  return self._map_async(func, iterable, mapstar, chunksize).get()

可以看到,map函数的第二个参数iterable接收的是单个可迭代对象。面对多参数情况,直观想法是使用zip函数将多个参数列表打包组合:


if __name__ == "__main__":
  x = [1, 2, 3, 4, 5]
  y = [1, 1, 1, 1, 1]
  zip_args = list(zip(x, y))
  pool = Pool()
  pool.map(my_print, zip_args)
  pool.close()
  pool.join()

然而实际执行后发现,y参数并未被正确传递至目标函数:

那么,如何正确向多进程函数传递多个参数?这正是本文要解决的核心问题,请继续阅读后续内容。

解决方案

2. 解决方案

使用偏函数(partial)

2.1 使用偏函数(partial)

偏函数的概念类似于数学中的偏导数,允许我们在调用时固定部分参数,仅关注剩余变量的变化。在前述例子中,若y始终固定为1,则在传入参数时只需考虑x的变化即可。

例如,假设有一个函数接收两个参数a和b,其中a代表不同路径下的图片文件路径,b代表输出保存路径。显然,a是动态变化的,而为了将所有图片保存至同一文件夹,b通常保持不变。

具体实现如下:


if __name__ == '__main__':# 多线程,多参数,partial版本
  x = [1, 2, 3, 4, 5]
  y = 1
 
  partial_func = partial(my_print, y=y)
  pool = Pool()
  pool.map(partial_func, x)
  pool.close()
  pool.join()

使用可变参数

2.2 使用可变参数

Python函数支持定义可变参数。所谓可变参数,即传入的参数个数不固定,可以是1个、2个或任意多个。基于此特性,我们可以构造一个包装函数来接收打包后的参数。具体实现如下:


def multi_wrapper(args):
  return my_print(*args)
 
def my_print(x, y):
  print(x + y)
if __name__ == "__main__": # 多线程,多参数,可变参数版本
  x = [1, 2, 3, 4, 5]
  y = [1, 1, 1, 1, 1]
  zip_args = list(zip(x, y))
 
  pool = Pool()
  pool.map(multi_wrapper, zip_args)
  pool.close()
  pool.join()

使用pathos提供的多进程库

2.3 使用pathos提供的多进程库


from pathos.multiprocessing import ProcessingPool as newPool
 
if __name__ == '__main__':# 多线程,多参数,pathos版本
  x = [1, 2, 3, 4, 5]
  y = [1, 1, 1, 1, 1]
 
  pool = newPool()
  pool.map(my_print, x, y)
  pool.close()
  pool.join()

pathos库中的map函数允许直接输入多个参数列表,其底层实现同样利用了可变参数机制。具体代码如下:


def map(self, f, *args, **kwds):
  AbstractWorkerPool._AbstractWorkerPool__map(self, f, *args, **kwds)
  _pool = self._serve()
  return _pool.map(star(f), zip(*args)) # chunksize

使用starmap函数

2.4 使用starmap函数


if __name__ == '__main__': # 多线程,多参数,starmap版本
  x = [1, 2, 3, 4, 5]
  y = [1, 1, 1, 1, 1]
 
  zip_args = list(zip(x, y))
  pool = Pool()
  pool.starmap(my_print, zip_args)
  pool.close()
  pool.join()

总结

3. 总结

综上所述,上述4种实现方式中,第1种(偏函数)限制较多,若函数其他参数也动态变化,则适用性较差。其余三种方法在体验上依次提升,均支持任意数量参数输入。但第2种方法需额外编写包装函数,略显繁琐;第3种方法需额外安装pathos第三方包;而第4种方法无需任何额外依赖即可完成,因此推荐优先选择第4种方法。

以上关于Python多进程处理含任意参数函数的内容分享完毕,希望能对大家有所帮助。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表