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错误处理详解
Sep 28 Python
简单介绍Python中的JSON使用
Apr 28 Python
Python利用ansible分发处理任务
Aug 04 Python
Python模拟三级菜单效果
Sep 11 Python
Django入门使用示例
Dec 12 Python
Python中字典的浅拷贝与深拷贝用法实例分析
Jan 02 Python
python查看模块安装位置的方法
Oct 16 Python
pycharm 批量修改变量名称的方法
Aug 01 Python
TensorFlow MNIST手写数据集的实现方法
Feb 05 Python
Python reversed函数及使用方法解析
Mar 17 Python
详解Python中Pyyaml模块的使用
Oct 08 Python
深入浅析python3 依赖倒置原则(示例代码)
Jul 09 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实现的62进制转10进制,10进制转62进制函数示例
2019/06/06 PHP
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
Javascript将string类型转换int类型
2010/12/09 Javascript
JSON语法五大要素图文介绍
2012/12/04 Javascript
JS对话框_JS模态对话框showModalDialog用法总结
2014/01/11 Javascript
JS文本获得焦点清除文本文字的示例代码
2014/01/13 Javascript
jQuery使用正则表达式替换dom元素标签用法示例
2017/01/16 Javascript
JS组件系列之JS组件封装过程详解
2017/04/28 Javascript
angularJS 发起$http.post和$http.get请求的实现方法
2017/05/18 Javascript
vue中使用cropperjs的方法
2018/03/01 Javascript
深入浅析Vue中的 computed 和 watch
2018/06/06 Javascript
no-vnc和node.js实现web远程桌面的完整步骤
2019/08/11 Javascript
JavaScript JSON数据处理全集(小结)
2019/08/15 Javascript
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
Paypal支付不完全指北
2020/06/04 Javascript
Bootstrap告警框(alert)实现弹出效果和短暂显示后上浮消失的示例代码
2020/08/27 Javascript
解决vue页面刷新,数据丢失的问题
2020/11/24 Vue.js
分析Python的Django框架的运行方式及处理流程
2015/04/08 Python
python用10行代码实现对黄色图片的检测功能
2015/08/10 Python
Django ORM 常用字段与不常用字段汇总
2019/08/09 Python
python脚本执行CMD命令并返回结果的例子
2019/08/14 Python
Python 获取指定文件夹下的目录和文件的实现
2019/08/30 Python
python接口自动化之ConfigParser配置文件的使用详解
2020/08/03 Python
使用javascript和HTML5 Canvas画的四渐变色播放按钮效果
2014/04/10 HTML / CSS
Parfume Klik丹麦:香水网上商店
2018/07/10 全球购物
网络工程专业大学生求职信
2014/10/01 职场文书
学生自我评语
2015/01/04 职场文书
公司仓管员岗位职责
2015/04/01 职场文书
会议通知范文
2015/04/15 职场文书
民间借贷借条如何写
2015/05/26 职场文书
工程移交协议书
2016/03/24 职场文书
创业计划书之健康营养产业
2019/10/15 职场文书
Redis 彻底禁用RDB持久化操作
2021/07/09 Redis
win11怎么用快捷键锁屏? windows11锁屏的几种方法
2021/11/21 数码科技
解析python中的jsonpath 提取器
2022/01/18 Python
一文了解MYSQL三大范式和表约束
2022/04/03 MySQL