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 UnicodeEncodeError: 'gbk' codec can't encode character 解决方法
Apr 24 Python
在Windows中设置Python环境变量的实例讲解
Apr 28 Python
Python线性拟合实现函数与用法示例
Dec 13 Python
对python捕获ctrl+c手工中断程序的两种方法详解
Dec 26 Python
Python多图片合并PDF的方法
Jan 03 Python
django 读取图片到页面实例
Mar 27 Python
基于python图像处理API的使用示例
Apr 03 Python
Python3 ffmpeg视频转换工具使用方法解析
Aug 10 Python
python如何将图片转换素描画
Sep 08 Python
python中lower函数实现方法及用法讲解
Dec 23 Python
python中如何对多变量连续赋值
Jun 03 Python
python实现简单石头剪刀布游戏
Oct 24 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
如何把PHP转成EXE文件
2006/10/09 PHP
php二维数组排序详解
2013/11/06 PHP
PHP empty函数报错解决办法
2014/03/06 PHP
MooTools 页面滚动浮动层智能定位实现代码
2011/08/23 Javascript
javascript 基础篇4 window对象,DOM
2012/03/14 Javascript
JS中类或对象的定义说明
2014/03/10 Javascript
jQuery scroll事件实现监控滚动条分页示例
2014/04/04 Javascript
JavaScript代码应该放在HTML代码哪个位置比较好?
2014/10/16 Javascript
javascript鼠标滑动评分控件完整实例
2015/05/13 Javascript
全屏js头像上传插件源码高清版
2016/03/29 Javascript
理解JavaScript原型链
2016/10/25 Javascript
Vue header组件开发详解
2018/01/26 Javascript
vue里的data要用return返回的原因浅析
2019/05/28 Javascript
vue实现节点增删改功能
2019/09/26 Javascript
JavaScript中reduce()的5个基本用法示例
2020/07/19 Javascript
在vs code 中如何创建一个自己的 Vue 模板代码
2020/11/10 Javascript
详细探究Python中的字典容器
2015/04/14 Python
python 实现网上商城,转账,存取款等功能的信用卡系统
2016/07/15 Python
Python编程实现输入某年某月某日计算出这一天是该年第几天的方法
2017/04/18 Python
TensorFlow神经网络优化策略学习
2018/03/09 Python
Python实现string字符串连接的方法总结【8种方式】
2018/07/06 Python
Python File(文件) 方法整理
2019/02/18 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
python3 动态模块导入与全局变量使用实例
2019/12/22 Python
pytorch 批次遍历数据集打印数据的例子
2019/12/30 Python
pyCharm 实现关闭代码检查
2020/06/09 Python
CSS3中几个新增加的盒模型属性使用教程
2016/03/01 HTML / CSS
印度首选时尚目的地:Reliance Trends
2018/01/17 全球购物
美国运动鞋和服装网上商店:YCMC
2018/09/15 全球购物
瑞士领先的网上超市:LeShop.ch
2018/11/14 全球购物
美国在线肉类和海鲜配送:Crowd Cow
2020/10/02 全球购物
工厂门卫的岗位职责
2014/07/27 职场文书
处级干部考察材料
2014/12/24 职场文书
烟台的海导游词
2015/02/02 职场文书
少先队工作总结2015
2015/05/13 职场文书
2019让人心动的商业计划书
2019/06/27 职场文书