关于python:关键字在打开文件时有效,但在调用函数时无效

with keyword works when openning file but not when calling a function

我正在试验多处理模块,并从这个页面复制示例代码。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/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

运行此代码后,我得到:

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

不知怎么的,我发现这是由于with关键字造成的。但是,此代码也在使用with,它正在运行:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/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()

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[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关键字时会出错,这些代码(with和try catch)是否等价?我使用的是python 2.7.10。


(P)这个PEP描述了背景经理界面,需要使用"与"Keyword。Python 2.7's version of the pool class does not support this interface so you cannot use the'with'keyword in the way you described.(p)(P)You can just rewrite the code to not use with and join/terminate the pool directly as in the example here or you can upgrade to pyton 3 which does support'with'for pools.(p)


(P)You have wrongly assumed that the multiprocessor pool class of pyton 2.7 returns a context manager.Instead it returns a list of worker processes.The pool was converted to a context manager object from pyton 3.4.3 and if your version predates that,you cannot use it with a context manager.(p)(P)要使用有声明的方式,表达应当返回一个目标,包含完整和有效的方法,这样你就有了家庭错误。(p)字母名称