在Lambda中生成器的行为能否抵御未来变化?

3 投票
1 回答
1848 浏览
提问于 2025-04-17 03:12

我有一个这样的函数:

|    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

撰写回答