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 difflib模块示例讲解
Sep 13 Python
Pandas中把dataframe转成array的方法
Apr 13 Python
Python把csv数据写入list和字典类型的变量脚本方法
Jun 15 Python
python递归函数绘制分形树的方法
Jun 22 Python
在Python中分别打印列表中的每一个元素方法
Nov 07 Python
Python3爬虫之urllib携带cookie爬取网页的方法
Dec 28 Python
python三引号输出方法
Feb 27 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
Jun 13 Python
Python算法的时间复杂度和空间复杂度(实例解析)
Nov 19 Python
利用python中的matplotlib打印混淆矩阵实例
Jun 16 Python
python如何进入交互模式
Jul 06 Python
python基础之文件处理知识总结
May 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
laravel 5 实现模板主题功能
2015/03/02 PHP
分享PHP计算两个日期相差天数的代码
2015/12/23 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
2018/02/06 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
40款非常棒的jQuery 插件和制作教程(系列二)
2011/11/02 Javascript
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
javascript实现的闭包简单实例
2015/07/17 Javascript
[原创]Javascript 实现广告后加载 可加载百度谷歌联盟广告
2016/05/11 Javascript
js显示动态时间的方法详解
2016/08/20 Javascript
node.js爬虫爬取拉勾网职位信息
2017/03/14 Javascript
js中toString()和String()区别详解
2017/03/23 Javascript
[01:11]steam端dota2实名认证操作流程视频
2021/03/11 DOTA
python解析json实例方法
2013/11/19 Python
Python实现批量检测HTTP服务的状态
2016/10/27 Python
Python操作MySQL数据库的方法
2018/06/20 Python
编写多线程Python服务器 最适合基础
2018/09/14 Python
详解python和matlab的优势与区别
2019/06/28 Python
python matplotlib库绘制散点图例题解析
2019/08/10 Python
基于Python解密仿射密码
2019/10/21 Python
Pytorch实现基于CharRNN的文本分类与生成示例
2020/01/08 Python
Python爬虫工具requests-html使用解析
2020/04/29 Python
在python下实现word2vec词向量训练与加载实例
2020/06/09 Python
Keras中的两种模型:Sequential和Model用法
2020/06/27 Python
python Tornado框架的使用示例
2020/10/19 Python
Html5剪切板功能的实现代码
2018/06/29 HTML / CSS
哪些情况下不应该使用索引
2015/07/20 面试题
什么是规则表达式
2012/05/03 面试题
广告学专业应届生求职信
2013/10/01 职场文书
培训主管的岗位职责
2013/11/23 职场文书
大学自我鉴定范文
2013/12/26 职场文书
大学自主招生推荐信
2014/05/10 职场文书
离婚协议书标准格式
2014/10/04 职场文书
幼儿园园长安全责任书
2015/05/08 职场文书
2016春季运动会通讯稿
2015/07/18 职场文书
numpy数据类型dtype转换实现
2021/04/24 Python
Vue实现动态查询规则生成组件
2021/05/27 Vue.js