I wrote a line of code using lambda to clo开发者_JAVA百科se a list of file objects in python2.6:
map(lambda f: f.close(), files)
It works, but doesn't in python3.1. Why?
Here is my test code:
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
map
returns a list in Python 2, but an iterator in Python 3. So the files will be closed only if you iterate over the result.
Never apply map
or similar "functional" functions to functions with side effects. Python is not a functional language, and will never be. Use a for
loop:
for o in files:
o.close()
Because map in Python 3 is a lazy iterator. Quoting the docs:
Return an iterator that applies function to every item of iterable, yielding the results.
E.g. in Python 2, map(f, seq)
equivalent to [f(i) for i in seq]
, but in Python 3, it's (f(i) for i in seq)
- subtly different syntax, but very different semantics. To make the map variant work, you'd need to consume the iterator. Ergo, it's simpler (and more idiomatic: map, comprehension and generators shouldn't have side effects!) to use an explicit for-loop.
精彩评论