web-dev-qa-db-fra.com

Python Utilisation de la liste / plusieurs arguments dans la carte du pool

J'essaie de passer une liste en tant que paramètre à la pool.map(co_refresh, input_list). Pourtant, pool.map n'a pas déclenché la fonction co_refresh. Et aussi aucune erreur retournée. Il semble que le processus ait été suspendu.

Code d'origine:

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()

Cependant, il n'a jamais déclenché la fonction co_refresh. Comment utiliser la liste comme paramètre à transmettre à ma fonction?

Ancienne question (simplifiée):

J'ai ci-dessous input_list, qui est un list de list:

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

J'ai la fonction comme ci-dessous:

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

Je voudrais utiliser le multiprocess pour cette fonction func:

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

Cependant, il n'a jamais déclenché la fonction func. Comment utiliser la liste comme paramètre à transmettre à ma fonction?

8
lovechillcool

Vous devez définir votre fonction de travail avant de déclarer Pool, lorsque vous déclarez Pool, sub worker processus forked à partir de ce point, le processus de travail n'exécute pas de code au-delà de cette ligne, donc ne voit pas votre fonction de travail.

En outre, vous feriez mieux de remplacer pool.map avec pool.starmap pour correspondre à votre saisie.

Un exemple simplifié:

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()
11
georgexsh

Considérez le code ci-dessous

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)

Lorsque vous appelez cela dans votre script à l'aide d'un pool

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

La sortie est

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

Donc a obtient le tableau et reste tous les paramètres ne sont pas passés. Pool.map attend qu'une fonction n'ait qu'un seul argument. Donc, pour que votre cas fonctionne, vous devez créer une fonction wrapper

def someaction_wrapper(data):
    someaction(*data)

Et puis appelez cette fonction wrapper dans le pool. Maintenant vous utilisez

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

Et la sortie est

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

C'est ce que tu voulais je crois

1
Tarun Lalwani

la réponse de georgexsh fonctionne parfaitement dans Python 3; la clé est que starmap permet de passer plusieurs arguments dans la fonction.

Cependant, si vous utilisez Python 2, vous devrez utiliser python déballage classique mentionné dans les commentaires d'Ahmed sous la question ici .

Dans mon cas, je dois juste "enrôler" l'argument d'abord dans la fonction.

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