从上下文管理器中取出生成器
Taking a generator out of a context manager
我刚看到下面的代码:
from __future__ import print_function
from future_builtins import map # generator
with open('test.txt', 'r') as f:
linegen = map(str.strip, f)
# file handle should be closed here
for line in linegen:
# using the generator now
print(line)
在这种情况下会发生什么?上下文管理器是否足够聪明,知道 linegen
仍然有对文件句柄的引用,以便在上下文离开时它不会关闭?还是这可能不安全?
这是 Python 3.
中的重大更改之一
你的问题标题(Taking a generator ...)暗示你正在阅读它作为 Python 3 代码。
但是声明
from __future__ import print_function
表示它是为 Python 2
编写的
在 Python 2 中,map
returns 一个实际的列表 - 因此这段代码既非常安全又非常明智(即打开一个文件,读取所有行,跳闸然后关闭文件)
In [2]: with open('README.md','r') as f:
...: lines = map(str.strip, f)
...:
In [3]: lines
Out[3]:
['ASM',
'============',
'',
在Python3中,同样的代码抛出异常
In [1]: with open('README.md','r') as f:
lines = map(str.strip, f)
...:
In [2]: lines
Out[2]: <map at 0x7f4d393c3ac8>
In [3]: list(lines)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-2666a44c63b5> in <module>()
----> 1 list(lines)
ValueError: I/O operation on closed file.
如果你想要 version-safe 实现它,你需要将生成器转换为列表
lines = list(map(str.strip, f))
或者只使用列表理解
lines = [l.strip() for l in f]
我刚看到下面的代码:
from __future__ import print_function
from future_builtins import map # generator
with open('test.txt', 'r') as f:
linegen = map(str.strip, f)
# file handle should be closed here
for line in linegen:
# using the generator now
print(line)
在这种情况下会发生什么?上下文管理器是否足够聪明,知道 linegen
仍然有对文件句柄的引用,以便在上下文离开时它不会关闭?还是这可能不安全?
这是 Python 3.
中的重大更改之一你的问题标题(Taking a generator ...)暗示你正在阅读它作为 Python 3 代码。
但是声明
from __future__ import print_function
表示它是为 Python 2
编写的在 Python 2 中,map
returns 一个实际的列表 - 因此这段代码既非常安全又非常明智(即打开一个文件,读取所有行,跳闸然后关闭文件)
In [2]: with open('README.md','r') as f:
...: lines = map(str.strip, f)
...:
In [3]: lines
Out[3]:
['ASM',
'============',
'',
在Python3中,同样的代码抛出异常
In [1]: with open('README.md','r') as f:
lines = map(str.strip, f)
...:
In [2]: lines
Out[2]: <map at 0x7f4d393c3ac8>
In [3]: list(lines)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-2666a44c63b5> in <module>()
----> 1 list(lines)
ValueError: I/O operation on closed file.
如果你想要 version-safe 实现它,你需要将生成器转换为列表
lines = list(map(str.strip, f))
或者只使用列表理解
lines = [l.strip() for l in f]