Выбор ответа Senior Итераторы и генераторы обновлено

Когда выполняется finally в недочитанном генераторе

Вопрос

Генератор открывает файл в try/finally и выдаёт строки. Код прочитал две строки и перестал итерировать, сохранив ссылку на генератор. Когда выполнится finally?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: При g.close() или при сборке генератора. close() бросает в точку yield исключение GeneratorExit, и выполняются finally и exit.

Варианты ответа

  1. Сразу после второго next
  2. Никогда: finally в генераторах не выполняется
  3. При g.close() или при сборке генератораправильный ответ
  4. При следующем next, даже если он не нужен

Разбор

close() бросает в точку yield исключение GeneratorExit, и выполняются finally и __exit__. Если явно не закрыть, это сделает финализатор при уничтожении объекта, в CPython обычно сразу после потери последней ссылки, в других реализациях позже. Поэтому для ресурсов надёжнее with closing(gen) или контекстный менеджер снаружи генератора. Сам по себе finally не срабатывает между next, и после ухода со строки ничего не произойдёт, пока жива ссылка.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме