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使用自带的ConfigParser模块读写ini配置文件
Jun 26 Python
浅谈python内置变量-reversed(seq)
Jun 21 Python
python自定义异常实例详解
Jul 11 Python
python XlsxWriter模块创建aexcel表格的实例讲解
May 03 Python
学习python分支结构
May 17 Python
如何在Django项目中引入静态文件
Jul 26 Python
Python 分发包中添加额外文件的方法
Aug 16 Python
python实现的发邮件功能示例
Sep 11 Python
python3 assert 断言的使用详解 (区别于python2)
Nov 27 Python
Python使用turtle库绘制小猪佩奇(实例代码)
Jan 16 Python
python 的numpy库中的mean()函数用法介绍
Mar 03 Python
python - asyncio异步编程
Apr 06 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中批量替换文件名的实现代码
2011/07/20 PHP
php数组随机排序实现方法
2015/06/13 PHP
Yii清理缓存的方法
2016/01/06 PHP
PHP 500报错的快速解决方法
2016/12/14 PHP
javascript 放大镜效果js组件 qsoft.PopBigImage.v0.35 加入了chrome支持
2009/04/07 Javascript
JQuery中如何传递参数如click(),change()等具体实现
2013/04/28 Javascript
js实现倒计时时钟的示例代码
2013/12/17 Javascript
用js将内容复制到剪贴板兼容浏览器
2014/03/18 Javascript
JS控制输入框内字符串长度
2014/05/21 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
判断JS对象是否拥有某属性的方法推荐
2016/05/12 Javascript
老生常谈 关于JavaScript的类的继承
2016/06/24 Javascript
javascript时间差插件分享
2016/07/18 Javascript
深入理解JavaScript中Ajax
2016/08/02 Javascript
js中创建对象的几种方式
2017/02/05 Javascript
Bootstrap 3浏览器兼容性问题及解决方案
2017/04/11 Javascript
Vue动态组件实例解析
2017/08/20 Javascript
解决layer弹出层的内容页点击按钮跳转到新的页面问题
2019/09/14 Javascript
代码块高亮可复制显示js插件highlight.js+clipboard.js整合
2021/02/15 Javascript
Python操作列表的常用方法分享
2014/02/13 Python
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
2016/07/12 Python
python安装oracle扩展及数据库连接方法
2017/02/21 Python
Python的地形三维可视化Matplotlib和gdal使用实例
2017/12/09 Python
python函数enumerate,operator和Counter使用技巧实例小结
2020/02/22 Python
基于matplotlib中ion()和ioff()的使用详解
2020/06/16 Python
HTML5中的网络存储实现方式
2020/04/28 HTML / CSS
德国BA保镖药房韩文网:kr.ba.de
2017/09/04 全球购物
西班牙语在线票务市场:SuperBoletería
2019/06/10 全球购物
商业活动邀请函
2014/02/04 职场文书
信息管理应届生求职信
2014/03/07 职场文书
广告词串烧
2014/03/19 职场文书
财务科长个人对照检查材料
2014/09/18 职场文书
事业单位岗位说明书
2015/10/08 职场文书
python自动化之如何利用allure生成测试报告
2021/05/02 Python
浅谈golang package中init方法的多处定义及运行顺序问题
2021/05/06 Golang
python实现简易自习室座位预约系统
2021/06/30 Python