我刚刚看到以下代码:
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
仍然具有对文件句柄的引用,以便在保留上下文时它不会关闭?或者这可能不安全吗?
答案 0 :(得分:2)
这是Python 3中的重大变化之一。
您的问题标题(使用生成器 ...)意味着您正在将其作为Python 3代码阅读。
但声明
from __future__ import print_function
暗示它是为Python 2编写的
在Python 2中,map
返回一个实际的列表 - 因此这段代码非常安全且非常合理(即打开一个文件,读取所有行,然后跳转它们,然后关闭文件)
In [2]: with open('README.md','r') as f:
...: lines = map(str.strip, f)
...:
In [3]: lines
Out[3]:
['ASM',
'============',
'',
在Python 3中,相同的代码抛出异常
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.
如果您想要版本安全的实现,您需要将生成器转换为列表
lines = list(map(str.strip, f))
或只使用列表理解
lines = [l.strip() for l in f]