Поведение генератора в лямбде безопасно от будущих изменений? - PullRequest
3 голосов
/ 27 сентября 2011

У меня есть следующая функция:

|    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))

Ясно, что лямбда работает только потому, что кажется, что есть разница во времени компиляции противПоведение во время выполнения, которое очень приветствуется: line_reader_iter () помещает ссылку на объект итератора в лямбда-выражение вместо создания объекта генератора каждый раз, когда лямбда-выражение оценивается.НО: это портативное и стабильное поведение?Я просто новичок в Python, и я не знаю, находится ли мой код в серой области относительно модели исполнения Python.Может ли кто-нибудь меня просветить?

slarti

1 Ответ

7 голосов
/ 27 сентября 2011

Я думаю, вы на самом деле не понимаете, почему это работает. Каждый раз, когда вы звоните 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
...