我使用lambda编写了一行代码来关闭python2.6中的文件对象列表:
map(lambda f: f.close(), files)
它可以工作,但不在python3.1中。为什么呢?
这是我的测试代码:
import sys
files = [sys.stdin, sys.stderr]
for f in files: print(f.closed) # False in 2.6 & 3.1
map(lambda o : o.close(), files)
for f in files: print(f.closed) # True in 2.6 but False in 3.1
for f in files: f.close()
for f in files: print(f.closed) # True in 2.6 & 3.1
答案 0 :(得分:6)
map
在Python 2中返回一个列表,但在Python 3中返回一个迭代器。因此,只有在迭代结果时才会关闭文件。
永远不要将map
或类似的“功能”功能应用于具有副作用的功能。 Python不是一种功能语言,永远不会。使用for
循环:
for o in files:
o.close()
答案 1 :(得分:4)
因为Python 3中的map是一个惰性迭代器。引用the docs:
返回一个迭代器,它将函数应用于每个iterable项,产生结果。
E.g。在Python 2中,map(f, seq)
等同于[f(i) for i in seq]
,但在Python 3中,它是(f(i) for i in seq)
- 语法略有不同,但语义却截然不同。要使map变量起作用,您需要使用迭代器。因此,使用显式的for循环更简单(并且更惯用:地图,理解和生成器不应该有副作用!)。