【问题标题】:Python Using List/Multiple Arguments in Pool MapPython 在池映射中使用列表/多个参数
【发布时间】:2018-05-05 13:53:34
【问题描述】:

我正在尝试将列表作为参数传递给pool.map(co_refresh, input_list)。但是,pool.map 并没有触发函数co_refresh。而且也没有返回错误。看起来进程挂在那里。

原始代码:

from multiprocessing import Pool
import pandas as pd
import os

account='xxx'
password='xxx'
threads=5
co_links='file.csv'

input_list=[]

pool = Pool(processes=threads)
def co_refresh(url, account, password, outputfile):

    print(url + ' : ' + account + ' : ' + password + ' : ' + outputfile)

    return;

link_pool = pd.read_csv(co_links, skipinitialspace = True)

for i, row in link_pool.iterrows():

    ln = (row.URL, account, password, os.path.join('e:/', row.File_Name.split('.')[0] + '.csv'))

    input_list.append(ln)

pool.map(co_refresh, input_list)

pool.close()

但是,它从未触发函数co_refresh。如何使用列表作为参数传递给我的函数?

老问题(简体):

我有下面的 input_list,这是 listlist

[a1, b1, c1, d1]
[a2, b2, c2, d2]
[a3, b3, c3, d3]

我的功能如下:

def func(a, b, c, d)
   ###
    return;

我想为这个功能使用多进程func

from multiprocessing import Pool
pool = Pool(processes=5)
pool.map(func, input_list)
pool.close()

但是,它从未触发函数func。如何使用列表作为参数传递给我的函数?

【问题讨论】:

  • 这不完全是您测试的代码,是吗?它充满了错误。准确发布您尝试过的内容,然后您会得到准确的答案。
  • 正如@zvone 建议的那样,您应该与我们分享您测试过的确切代码以及Python 解释器报告的错误。目前您提供的部分不构成可运行的脚本。
  • 我已经更新了这个问题。 @Mai,你能帮忙吗?
  • 在脚本的顶层,你应该只定义函数和类,而不是实际执行它们。要执行的代码应该从 if __name__ == "__main__" 块中调用。这通常是一个好主意,但在多处理的情况下,这是必不可少的。多处理将在另一个进程中再次导入您的模块。事实上,这将导致所有的 coe 再次被执行,而不是你所期望的。

标签: python python-multiprocessing python-pool


【解决方案1】:

你应该在声明Pool之前定义你的工作函数,当你声明Poolsub worker processes forked时,工作进程不会执行超出该行的代码,因此不会查看您的工作职能。

此外,您最好将 pool.map 替换为 pool.starmap 以适应您的输入。

一个简化的例子:

from multiprocessing import Pool

def co_refresh(a, b, c, d):
    print(a, b, c, d)

input_list = [f'a{i} b{i} c{i} d{i}'.split() for i in range(4)]
# [['a0', 'b0', 'c0', 'd0'], ['a1', 'b1', 'c1', 'd1'], ['a2', 'b2', 'c2', 'd2'], ['a3', 'b3', 'c3', 'd3']]

pool = Pool(processes=3)
pool.starmap(co_refresh, input_list)
pool.close()

【讨论】:

  • 我终于有时间测试了...我现在明白问题出在哪里...但是,该过程已完成但没有打印任何内容。你知道这是为什么吗?
  • @lovechillcool 你在使用我发布的代码吗?请注意,它适用于 python3.6。
【解决方案2】:

考虑下面的代码

from multiprocessing.pool import Pool

data = [["a1", "b1", "c1", "d1"],
        ["a2", "b2", "c2", "d2"],
        ["a3", "b3", "c3", "d3"], ]


def someaction(a, b=1, c=2, d=3):
    print(a, b, c, d)

当您使用池在脚本中调用它时

pool = Pool(4)
pool.map(someaction, data)

输出是

['a1', 'b1', 'c1', 'd1'] 1 2 3
['a2', 'b2', 'c2', 'd2'] 1 2 3
['a3', 'b3', 'c3', 'd3'] 1 2 3

所以a 得到了数组,剩下的所有参数都没有传递。 Pool.map 期望函数只有一个参数。因此,要使您的案例正常工作,您需要创建一个包装函数

def someaction_wrapper(data):
    someaction(*data)

然后在池中调用这个包装函数。现在你使用

pool = Pool(4)
pool.map(someaction_wrapper, data)

输出是

a1 b1 c1 d1
a2 b2 c2 d2
a3 b3 c3 d3

我相信这是你想要的

【讨论】:

    【解决方案3】:

    georgexsh 的答案在 Python 3 中完美运行;关键是starmap 允许将多个参数传递给函数。

    但是,如果您使用 Python 2,则需要使用 Ahmed 在问题 here 下在 cmets 中提到的 Python 经典解包。

    就我而言,我只需要首先在函数中“登记”参数。

    def func(args)
       (a, b, c, d) = args
       # You can then use a, b, c, d in your function
        return;
    

    【讨论】:

      猜你喜欢
      • 2017-02-07
      • 1970-01-01
      • 2020-09-29
      • 2015-06-08
      • 1970-01-01
      • 2023-02-14
      • 2019-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多