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访问mysql数据库的实现方法(2则示例)
Jan 06 Python
Python 获取当前所在目录的方法详解
Aug 02 Python
python将list转为matrix的方法
Dec 12 Python
Python列表(list)所有元素的同一操作解析
Aug 01 Python
使用 python pyautogui实现鼠标键盘控制功能
Aug 04 Python
python3 实现的对象与json相互转换操作示例
Aug 17 Python
PyCharm2018 安装及破解方法实现步骤
Sep 09 Python
python3.6连接mysql数据库及增删改查操作详解
Feb 10 Python
Python用类实现扑克牌发牌的示例代码
Jun 01 Python
树莓派4B安装Tensorflow的方法步骤
Jul 16 Python
python非标准时间的转换
Jul 25 Python
Python使用Opencv打开笔记本电脑摄像头报错解问题及解决
Jun 21 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
了解Joomla 这款来自国外的php网站管理系统
2010/03/11 PHP
PHP数组游标实现对数组的各种操作详解
2016/01/26 PHP
Joomla数据库操作之JFactory::getDBO用法
2016/05/05 PHP
修改Laravel5.3中的路由文件与路径
2016/08/10 PHP
js不完美解决click和dblclick事件冲突问题
2012/07/16 Javascript
JavaScript模拟可展开、拖动与关闭的聊天窗口实例
2015/05/12 Javascript
JavaScript 计算笛卡尔积实例详解
2016/12/02 Javascript
ReactNative 之FlatList使用及踩坑封装总结
2017/11/29 Javascript
vue实现微信分享功能
2018/11/28 Javascript
详解一个小实例理解js原型和继承
2019/04/24 Javascript
js+html实现周岁年龄计算器
2019/06/25 Javascript
Vue全局loading及错误提示的思路与实现
2019/08/09 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
2019/09/25 Javascript
JavaScript数组排序功能简单实现
2020/05/14 Javascript
学习python类方法与对象方法
2016/03/15 Python
python 读写中文json的实例详解
2017/10/29 Python
Django工程的分层结构详解
2019/07/18 Python
Python 使用 PyQt5 开发的关机小工具分享
2020/07/16 Python
CSS3简单实现照片墙
2014/12/12 HTML / CSS
html5各种页面切换效果和模态对话框用法总结
2014/12/15 HTML / CSS
国际书籍零售商:Wordery
2017/11/01 全球购物
S’well Bottle保温杯官网:绝缘不锈钢水瓶
2018/05/09 全球购物
英国床垫和床架购物网站:Bedman
2019/11/04 全球购物
Abbott Lyon官网:女士手表、珠宝及配件
2020/12/26 全球购物
优秀的自荐信要注意哪些
2014/01/03 职场文书
办理信用卡工作证明
2014/01/11 职场文书
大学生社会实践自我鉴定
2014/03/24 职场文书
《大江保卫战》教学反思
2014/04/11 职场文书
医生爱岗敬业演讲稿
2014/08/26 职场文书
2014年招商工作总结
2014/11/22 职场文书
作息时间调整通知
2015/04/22 职场文书
初中重阳节活动总结
2015/05/05 职场文书
2015年幼儿园国庆节活动总结
2015/07/30 职场文书
导游词之千岛湖
2019/09/23 职场文书
Python 的演示平台支持 WSGI 接口的应用
2022/04/20 Python
Win10玩csgo闪退如何解决?Win10玩csgo闪退的解决方法
2022/07/23 数码科技