with keyword在打开文件时有效但在调用函数时无效

时间:2015-08-31 19:17:03

标签: python multiprocessing

我尝试使用多处理模块并从this页面复制示例代码。这是一个例子:

#!/usr/bin/python
from multiprocessing import Pool
from time import sleep

def f(x):
    return x*x

if __name__ == '__main__':
    # start 4 worker processes
    with Pool(processes=4) as pool:

        # print "[0, 1, 4,..., 81]"
        print(pool.map(f, range(10)))

        # print same numbers in arbitrary order
        for i in pool.imap_unordered(f, range(10)):
            print(i)

        # evaluate "f(10)" asynchronously
        res = pool.apply_async(f, [10])
        print(res.get(timeout=1))             # prints "100"

        # make worker sleep for 10 secs
        res = pool.apply_async(sleep, [10])
        print(res.get(timeout=1))             # raises multiprocessing.TimeoutError

    # exiting the 'with'-block has stopped the pool

运行此代码后,我得到:

Traceback (most recent call last):
  File "example01.py", line 11, in <module>
    with Pool(processes=4) as pool:
AttributeError: __exit__

不知何故,我发现这是with个关键字造成的。但是,此代码也使用with并且正在运行:

#!/usr/bin/python
with open("input.csv", "wb") as filePath:
    pass
filePath.close()

当我想运行上述示例时,我必须按照以下方式修改它:

#!/usr/bin/python

from multiprocessing import Pool
from time import sleep
import traceback

def f(x):
    return x*x

if __name__ == '__main__':
  # start 4 worker processes
  # with Pool(processes=4) as pool:
  try:
    pool = Pool(processes = 4)

    # print "[0, 1, 4,..., 81]"
    print(pool.map(f, range(10)))

    # print same numbers in arbitrary order
    for i in pool.imap_unordered(f, range(10)):
      print(i)

    # evaluate "f(10)" asynchronously
    res = pool.apply_async(f, [10])
    print(res.get(timeout=1))             # prints "100"

    # make worker sleep for 10 secs
    res = pool.apply_async(sleep, [10])
    print(res.get(timeout=1))             # raises multiprocessing.TimeoutError

    # exiting the 'with'-block has stopped the pool

  # http://stackoverflow.com/questions/4990718/python-about-catching-any-exception
  # http://stackoverflow.com/questions/1483429/how-to-print-an-error-in-python
  # http://stackoverflow.com/questions/1369526/what-is-the-python-keyword-with-used-for
  except Exception as e:
    print "Exception happened:"
    print type(e)
    print str(e)
    print traceback.print_exc()

然后输出如下:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
0
1
4
9
16
25
36
49
64
81
100
Exception happened:
<class 'multiprocessing.TimeoutError'>

Traceback (most recent call last):
  File "example01_mod.py", line 29, in <module>
    print(res.get(timeout=1))             # raises multiprocessing.TimeoutError
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 563, in get
    raise TimeoutError
TimeoutError
None

为什么在使用with关键字时出现错误,这些代码(带有和try-catch)是否相同?我正在使用python 2.7.10。

2 个答案:

答案 0 :(得分:2)

This PEP描述了使用'with'关键字所需的上下文管理器界面。 Python 2.7版本的Pool类不支持此接口,因此您无法按照描述的方式使用“with”关键字。

你可以像the example here那样直接重写不使用的代码并直接加入/终止池,或者你可以升级到支持池的'with'的Python 3。

答案 1 :(得分:1)

您错误地认为multiprocessor Pool class of Python 2.7会返回context manager。而是返回worker processes的列表。池已从Python 3.4.3转换为上下文管理器对象,如果您的版本早于此版本,则无法将其与上下文管理器一起使用。

要与with语句一起使用,表达式应返回一个带有输入退出方法的对象,以便您得到熟悉的错误。

AttributeError: __exit_