Ошибка многопроцессорной обработки Python Lib (AttributeError: __exit__)

Получаем эту ошибку при использовании pool.map(funct, iterable):

AttributeError: __exit__

Нет пояснения, только трассировка стека в файл pool.py внутри модуля.

используя таким образом:

with Pool(processes=2) as pool:
   pool.map(myFunction, mylist)
   pool.map(myfunction2, mylist2)

Я подозреваю, что может возникнуть проблема с picklability (python нуждается в pickle или преобразовать данные списка в поток байтов), но я не уверен, что это правда или если это как отлаживать.

EDIT: новый формат кода, который вызывает эту ошибку:

def governingFunct(list):
    #some tasks
    def myFunction():
         # function contents
    with closing(Pool(processes=2)) as pool:
         pool.map(myFunction, sublist)
         pool.map(myFunction2, sublist2)

ОШИБКА ПРОДУКТА:

PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

Ответы

Ответ 1

В Python 2.x и 3.0, 3.1 и 3.2, multiprocessing.Pool() объекты не являются менеджерами контекста. Вы не можете использовать их в инструкции with. Только в Python 3.3 и выше вы можете использовать их как таковые. Из документации Python 3 multiprocessing.Pool():

Новое в версии 3.3: Объекты пула теперь поддерживают протокол управления контекстом - см. Типы Контекстного Менеджера. __enter__() возвращает объект пула, а __exit__() вызывает terminate().

Для более ранних версий Python вы можете использовать contextlib.closing(), но учтите, что это вызовет pool.close(), а не pool.terminate(). Завершите вручную в этом случае:

from contextlib import closing

with closing(Pool(processes=2)) as pool:
    pool.map(myFunction, mylist)
    pool.map(myfunction2, mylist2)
    pool.terminate()

или создайте свой собственный менеджер контекста terminating():

from contextlib import contextmanager

@contextmanager
def terminating(thing):
    try:
        yield thing
    finally:
        thing.terminate()

with terminating(Pool(processes=2)) as pool:
    pool.map(myFunction, mylist)
    pool.map(myfunction2, mylist2)

Ответ 2

with statement для объекта, который имеет функции __enter__ и __exit__, т.е. Типы контекстного менеджера
multiprocessing.Pool - это не тип Контекстного менеджера. попробуйте сделать следующее:

pool = Pool(processes=2)
pool.map(myFunction, mylist)
pool.map(myfunction2, mylist2)