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:pandas合并csv文件的方法(图书数据集成)
Apr 12 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
Jul 18 Python
python抓取网页内容并进行语音播报的方法
Dec 24 Python
用Python获取摄像头并实时控制人脸的实现示例
Jul 11 Python
Python 仅获取响应头, 不获取实体的实例
Aug 21 Python
如何使用selenium和requests组合实现登录页面
Feb 03 Python
基于python实现计算两组数据P值
Jul 10 Python
python实现移动木板小游戏
Oct 09 Python
python获取天气接口给指定微信好友发天气预报
Dec 28 Python
Python命令行参数argv和argparse该如何使用
Feb 08 Python
tensorflow+k-means聚类简单实现猫狗图像分类的方法
Apr 28 Python
Python中的socket网络模块介绍
Jul 23 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原理的opcodes(操作码)
2010/10/26 PHP
PHP反射机制用法实例
2014/08/28 PHP
PHP实现文件上传与下载实例与总结
2016/03/13 PHP
php实现登录tplink WR882N获取IP和重启的方法
2016/07/20 PHP
thinkphp框架使用JWTtoken的方法详解
2019/10/10 PHP
基于jQuery的可用于选项卡及幻灯的切换插件
2011/03/28 Javascript
JQuery给网页更换皮肤的方法
2015/05/30 Javascript
getElementById().innerHTML与getElementById().value的区别
2016/10/27 Javascript
Javascrip实现文字跳动特效
2016/11/27 Javascript
Javascript this 函数深入详解
2016/12/13 Javascript
angularjs实现下拉列表的选中事件示例
2017/03/03 Javascript
Angular2 父子组件通信方式的示例
2018/01/29 Javascript
利用angular、react和vue实现相同的面试题组件
2018/02/19 Javascript
jquery实现二级导航下拉菜单效果实例
2019/05/14 jQuery
Element的el-tree控件后台数据结构的生成以及方法的抽取
2020/03/05 Javascript
js cavans实现静态滚动弹幕
2020/05/21 Javascript
vue移动端的左右滑动事件详解
2020/06/17 Javascript
[00:12]DAC2018 天才少年转战三号位,他的SOLO是否仍如昔日般强大?
2018/04/06 DOTA
python实现周期方波信号频谱图
2018/07/21 Python
python 输入一个数n,求n个数求乘或求和的实例
2018/11/13 Python
Numpy对数组的操作:创建、变形(升降维等)、计算、取值、复制、分割、合并
2019/08/28 Python
python 判断txt每行内容中是否包含子串并重新写入保存的实例
2020/03/12 Python
详解Python 循环嵌套
2020/07/09 Python
Python selenium实现断言3种方法解析
2020/09/08 Python
Ivory Isle Designs美国/加拿大:婚礼和活动文具公司
2018/08/21 全球购物
英国DIY汽车维修配件网站:DIY Car Service Parts
2019/08/30 全球购物
瑞典香水、须后水和美容产品购物网站:Parfym-Klick.se
2019/12/29 全球购物
请写出一段Python代码实现删除一个list里面的重复元素
2015/12/29 面试题
甲方资料员岗位职责
2013/12/13 职场文书
运动会跳远广播稿
2014/02/04 职场文书
社区交通安全实施方案
2014/03/22 职场文书
优秀学生评语大全
2014/04/25 职场文书
奥巴马竞选演讲稿
2014/05/15 职场文书
委托书格式
2014/08/01 职场文书
平安工地汇报材料
2014/08/19 职场文书
Python基础教程,Python入门教程(超详细)
2021/06/24 Python