Выбор ответа Middle Исключения и контекстные менеджеры обновлено

try/finally в @contextmanager

Вопрос

Почему в генераторе с @contextmanager код очистки ставят в finally вокруг yield?

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

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

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

Коротко

Правильный ответ: Ошибка тела with бросается в точку yield, код после не выполнится. Декоратор вызывает next() на входе и при выходе либо снова next(), либо gen.throw(exc) в точке yield.

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

  1. Ошибка тела with бросается в точку yield, код после не выполнитсяправильный ответ
  2. Без finally генератор не станет контекстным менеджером
  3. finally нужен, чтобы as получил значение из yield
  4. Иначе yield вернёт None вместо ресурса

Разбор

Декоратор вызывает next() на входе и при выходе либо снова next(), либо gen.throw(exc) в точке yield. Если тело with упало, строки после yield без try/finally не выполнятся, ресурс утечёт. Значение для as это то, что отдал yield, с finally оно не связано.

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

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