user1251007 user1251007 - 25 days ago 9
Python Question

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

I'm doing some multiprocessing python scripts using

multiprocessing.Pool
. These scripts look like the following:

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]"


When running this with Python 3.4, everything is fine. However, when using Python 2.6 or 3.1 I get this error:

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


Using Python 2.7 or 3.2, the error is essentially the same:

AttributeError: __exit__


Why does this happen and how can I circumvent this?

Answer Source

The documentation says that multiprocessing.pool supports the context management protocol (with statements) in Python version 3.3 and above.

New in version 3.3: Pool objects now support the context management protocol – see Context Manager Types. __enter__() returns the pool object, and __exit__() calls terminate().

So you either need a newer version of Python, or use one of the two following possibilities changing your code (tested with Python versions 2.6, 2.7, 3.1, 3.2):

  1. rewrite your code like this to eliminate the with statement:

    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. as pointed out in the comments, use 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)))