在Lambda中生成器的行为能否抵御未来变化?
我有一个这样的函数:
| def line_reader_iter(file_object):
| while True:
| a_line = file_object.readline()
| if len(a_line)==0: raise StopIteration
| yield a_line[:-1]
然后在某个地方我这样写:
| line_reader = lambda: next(line_reader_iter(infile))
很明显,这个lambda函数之所以能工作,是因为编译时和运行时的行为似乎有差别,这种情况是很不错的:line_reader_iter()把迭代器对象的引用放进了lambda表达式里,而不是每次评估lambda时都创建一个生成器对象。但是:这样的行为是可移植和稳定的吗?我只是个Python新手,不知道我的代码是否在Python执行模型的灰色地带。有人能给我解释一下吗?
slarti
1 个回答
7
我觉得你可能误解了为什么这个方法有效。每次你调用 line_reader()
时,都会创建一个新的 line_reader_iter
生成器。之所以看起来有效,是因为你每次都使用相同的 infile
,而每次调用 readline()
都会返回文件的下一行。
考虑下面这个更简单的例子:
>>> counter = lambda: next(iter(range(10)))
>>> counter()
0
>>> counter() # each time the lambda is called, a new range iter is created
0
你可以通过使用以下代码来实现你想要的效果:
line_reader = line_reader_iter(infile).next
下面是我的范围示例是如何工作的:
>>> counter = iter(range(10)).next
>>> counter()
0
>>> counter() # yay, we are actually using the same iterator
1