Python 2.7: как компенсировать отсутствующий pool.starmap? - PullRequest
0 голосов
/ 04 октября 2018

Я определил эту функцию

def writeonfiles(a,seed):
    random.seed(seed)

    f = open(a, "w+")
    for i in range(0,10):
        j = random.randint(0,10)
        #print j
        f.write(j)
    f.close()

Где a - строка, содержащая путь к файлу, а seed - целое число.Я хочу распараллелить простую программу таким образом, чтобы каждое ядро ​​выбирало один из доступных путей, которые я предоставляю, запускает его генератор случайных чисел и записывает некоторые случайные числа в эти файлы, например, если я передаю вектор

vector = [Test/file1.txt, Test/file2.txt] 

и семени

seeds = (123412, 989898), 

дает первому доступному ядру функцию

writeonfiles(Test/file1.txt, 123412) 

и второму ту же функцию с разными аргументами:

writeonfiles(Test/file2.txt, 989898)

Я просмотрел множество подобных вопросов здесь, в Stackoverflow, но не могу заставить работать какое-либо решение.Я попробовал:

def writeonfiles_unpack(args):
    return writeonfiles(*args)
if __name__ == "__main__":
     folder = ["Test/%d.csv" %i for i in range(0,4)]
     seed = [234124, 663123, 12345 ,123833]
     p = multiprocessing.Pool()
     p.map(writeonfiles, (folder,seed))

и выдал мне TypeError: writeonfiles () принимает ровно 2 аргумента (1 дано).

Я пробовал также

if __name__ == "__main__":
    folder = ["Test/%d.csv" %i for i in range(0,4)]
    seed = [234124, 663123, 12345 ,123833]
    p = multiprocessing.Process(target=writeonfiles, args= [folder,seed])
    p.start()

Ноэто дает мне
файл "/usr/lib/python2.7/random.py", строка 120, в seed super (Random, self) .seed (a) Ошибка типа: не подлежащий обработке тип: 'list'

Наконец, я попробовал contextmanager

 @contextmanager
 def poolcontext(*args, **kwargs):
     pool = multiprocessing.Pool(*args, **kwargs)
     yield pool
     pool.terminate()

if __name__ == "__main__":
    folder = ["Test/%d" %i for i in range(0,4)]
    seed = [234124, 663123, 12345 ,123833]
    a = zip(folder, seed)
    with poolcontext(processes = 3) as pool:
    results = pool.map(writeonfiles_unpack,a )

, и в результате получился файл "/usr/lib/python2.7/multiprocessing/pool.py", строка 572, в get get self._value

TypeError: объект 'module' не вызывается

1 Ответ

0 голосов
/ 05 октября 2018

В Python 2.7 отсутствует starmap метод пула из Python 3.3+.Вы можете преодолеть это, украсив вашу целевую функцию оболочкой, которая распаковывает аргумент-кортеж и вызывает целевую функцию:

import os
from multiprocessing import Pool
import random
from functools import wraps


def unpack(func):
    @wraps(func)
    def wrapper(arg_tuple):
        return func(*arg_tuple)
    return wrapper

@unpack
def write_on_files(a, seed):
    random.seed(seed)
    print("%d opening file %s" % (os.getpid(), a))  # simulate
    for _ in range(10):
        j = random.randint(0, 10)
       print("%d writing %d to file %s" % (os.getpid(), j, a))  # simulate


if __name__ == '__main__':

    folder = ["Test/%d.csv" % i for i in range(0, 4)]
    seed = [234124, 663123, 12345, 123833]

    arguments = zip(folder, seed)

    pool = Pool(4)
    pool.map(write_on_files, iterable=arguments)
    pool.close()
    pool.join()
...