当前位置: 首页 > 编程笔记 >

Python使用多进程运行含有任意个参数的函数

宣望
2023-03-14
本文向大家介绍Python使用多进程运行含有任意个参数的函数,包括了Python使用多进程运行含有任意个参数的函数的使用技巧和注意事项,需要的朋友参考一下

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参数并没有被传进去:

那么如何传入多个参数呢?这也就是本文的重点,接着往下看吧。

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实现接受任意个数参数的函数方法的使用技巧和注意事项,需要的朋友参考一下 这个功能倒也不是我多么急需的功能,只是恰好看到了,觉得或许以后会用的到。功能就是实现函数能够接受不同数目的参数。 其实,在C语言中这个功能是熟悉的,虽说实现的形式不太一样。C语言中的main函数是可以实现类似的功能的,可以通过这种方式实现一个支持命令行

  • 我想使用jython执行一个Python函数,这个函数位于我的一个Java Python项目中。https://smart bear . com/blog/test-and-monitor/embedding-jython-in-Java-applications/给出了示例代码。但是在我的场景中,我得到了下面的异常。 线程“main”回溯中出现异常(最近一次调用是最后一次):文件“”中第1行,导

  • 问题内容: 在Python中,该模块可用于在一系列值上并行运行函数。例如,这将生成f的前100000个评估的列表。 当f接受多个输入而只有一个变量变化时,是否可以做类似的事情?例如,如何并行处理此: 问题答案: 有几种方法可以做到这一点。在问题给出的示例中,您可以定义一个包装函数 然后将此包装传递给。一种更通用的方法是使用一个包装器,该包装器使用一个元组参数并将该元组解包为多个参数 或使用等效的l

  • 问题内容: 我该如何使用子流程模块运行bash脚本,必须为此提供几个参数? 这是我目前正在使用的: bash脚本似乎没有接受任何参数。非常感谢您提供任何见解! 问题答案: 将参数作为列表传递,请参阅docs中的第一个代码示例: 如果不是字符串;在传递到:之前将其转换为字符串。

  • 问题内容: 经过一些挖掘后,我可以这样运行Linux命令: 我想做的是,在远程计算机上运行以下命令: 我可以从终端成功完成此操作,但是当我尝试在Go中运行它时,出现以下错误: 更新 :为了方便起见,我更新了问题。 问题答案: 根据有关exec软件包的文档,程序名称和参数是方法的不同参数。您应该这样做: 如果您需要更详细的说明,还可以查看go.crypto / ssh 软件包。

  • 根据文档,可以为标志,但我找不到具体方法。我尝试了以下方法: = 我也试过: = 知道如何定义多个参数吗?