Python使用多进程运行含有任意个参数的函数


Posted in Python onMay 02, 2020

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

发现函数的参数是作为iter传进去的,但是我们现在有两个参数,自然想到使用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参数并没有被传进去:

Python使用多进程运行含有任意个参数的函数

那么如何传入多个参数呢?这也就是本文的重点,接着往下看吧。

2. 解决方案

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

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

在该库的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

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种方法!

以上这篇Python使用多进程运行含有任意个参数的函数就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用Python脚本生成Android SALT扰码的方法
Sep 18 Python
Python查找函数f(x)=0根的解决方法
May 07 Python
python轻松查到删除自己的微信好友
Jan 10 Python
Python编写简单的HTML页面合并脚本
Jul 11 Python
django使用图片延时加载引起后台404错误
Apr 18 Python
Python抽象和自定义类定义与用法示例
Aug 23 Python
Python中如何使用if语句处理列表实例代码
Feb 24 Python
python 读写文件包含多种编码格式的解决方式
Dec 20 Python
对tensorflow中的strides参数使用详解
Jan 04 Python
使用TensorFlow搭建一个全连接神经网络教程
Feb 06 Python
python对数组进行排序,并输出排序后对应的索引值方式
Feb 28 Python
python 发送邮件的四种方法汇总
Dec 02 Python
python多进程使用函数封装实例
May 02 #Python
Python中使用filter过滤列表的一个小技巧分享
May 02 #Python
python同时遍历两个list用法说明
May 02 #Python
python多线程实现同时执行两个while循环的操作
May 02 #Python
python 实现两个线程交替执行
May 02 #Python
Python中使用threading.Event协调线程的运行详解
May 02 #Python
浅谈Python3多线程之间的执行顺序问题
May 02 #Python
You might like
DC这些乐高系列动画电影你看过几部?
2020/04/09 欧美动漫
php Xdebug 调试扩展的安装与使用.
2010/03/13 PHP
PHP在字符断点处截断文字的实现代码
2011/04/21 PHP
php接口与接口引用的深入解析
2013/08/09 PHP
PHP浮点比较大小的方法
2016/02/14 PHP
PHP发送AT指令实例代码
2016/05/26 PHP
JavaScript 动态添加表格行 使用模板、标记
2009/10/24 Javascript
jQuery 处理网页内容的实现代码
2010/02/15 Javascript
js中查找最近的共有祖先元素的实现代码
2010/12/30 Javascript
js中substr,substring,indexOf,lastIndexOf的用法小结
2013/12/27 Javascript
jquery实现显示已选用户
2014/07/21 Javascript
jQuery实现垂直半透明手风琴特效代码分享
2015/08/21 Javascript
前端jquery部分很精彩
2016/05/03 Javascript
JS实现快速的导航下拉菜单动画效果附源码下载
2016/11/01 Javascript
canvas实现环形进度条效果
2017/03/23 Javascript
简单谈谈JS中的正则表达式
2017/09/11 Javascript
详解微信小程序Page中data数据操作和函数调用
2017/09/27 Javascript
解决vue 路由变化页面数据不刷新的问题
2018/03/13 Javascript
JS的函数调用栈stack size的计算方法
2018/06/24 Javascript
微信小程序异步API为Promise简化异步编程的操作方法
2018/08/14 Javascript
Javascript Web Worker使用过程解析
2020/03/16 Javascript
同时安装Python2 & Python3 cmd下版本自由选择的方法
2017/12/09 Python
Python 3.6打包成EXE可执行程序的实现
2019/10/18 Python
使用Python串口实时显示数据并绘图的例子
2019/12/26 Python
Django中的模型类设计及展示示例详解
2020/05/29 Python
利用css3径向渐变做一张优惠券的示例
2018/03/22 HTML / CSS
英国奢侈皮具品牌:Aspinal of London
2018/09/02 全球购物
初入社会应届生求职信
2013/11/18 职场文书
大学生创业项目方案
2014/03/08 职场文书
省级优秀毕业生主要事迹
2014/05/29 职场文书
酒店七夕情人节活动策划方案
2014/08/24 职场文书
2015年扶贫帮困工作总结
2015/05/20 职场文书
入团介绍人意见范文
2015/06/04 职场文书
导游词之青岛崂山
2019/12/27 职场文书
用python删除文件夹中的重复图片(图片去重)
2021/05/12 Python
MySQL悲观锁与乐观锁的实现方案
2021/11/02 MySQL