AttributeError: у объекта 'Pool' нет атрибута '__exit__'

Я делаю несколько многопроцессорных скриптов Python, используя multiprocessing.Pool, Эти сценарии выглядят следующим образом:

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(processes=4) as pool:         # start 4 worker processes
        print(pool.map(f, range(10)))       # prints "[0, 1, 4,..., 81]"

При запуске этого с Python 3.4 все в порядке. Однако при использовании Python 2.6 или 3.1 я получаю эту ошибку:

AttributeError: 'Pool' object has no attribute '__exit__'

При использовании Python 2.7 или 3.2 ошибка по сути та же:

AttributeError: __exit__

Почему это происходит и как я могу обойти это?

1 ответ

Решение

В документации сказано, что multiprocessing.pool поддерживает протокол управления контекстом (with заявления) в Python версии 3.3 и выше.

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

Поэтому вам либо нужна более новая версия Python, либо используйте одну из двух следующих возможностей для изменения вашего кода (протестировано с версиями Python 2.6, 2.7, 3.1, 3.2):

  1. переписать свой код, как это, чтобы устранить with заявление:

    from multiprocessing import Pool
    
    def f(x):
        return x*x
    
    if __name__ == '__main__':
        pool = Pool(processes=4)            # start 4 worker processes
        print(pool.map(f, range(10)))       # prints "[0, 1, 4,..., 81]"
        pool.terminate()
    
  2. как указано в комментариях, используйте contextlib.closing():

    from multiprocessing import Pool
    import contextlib
    
    def f(x):
        return x*x
    
    if __name__ == '__main__':
        with contextlib.closing(Pool(processes=4)) as pool:
            print(pool.map(f, range(10)))
    
Другие вопросы по тегам