Ответ вслух Middle Функции и области видимости спрашивают часто обновлено

Замыкания в Python

Вопрос

Что такое замыкание в Python? Расскажите про nonlocal и про ловушку с лямбдами в цикле.

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

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

Коротко

Образцовый ответ: «Замыкание это вложенная функция, которая использует имена из охватывающей функции и сохраняет к ним доступ после того, как внешняя функция вернула результат. CPython кладёт такие переменные в объекты-ячейки, и у вложенной функции есть closure с этими ячейками.

Что должно прозвучать в ответе

  • Вложенная функция, которая использует переменные внешней после её завершения

  • Переменные лежат в ячейках, видно через `__closure__`

  • Связывается переменная, а не значение: позднее связывание

  • Для изменения переменной внешней функции нужен `nonlocal`

  • Применение: фабрики функций, декораторы, счётчики, колбэки

  • Лечение позднего связывания: аргумент по умолчанию или partial

Что могут спросить следом

  • Чем nonlocal отличается от global?
  • Можно ли заменить замыкание классом и когда это лучше?
  • Что выведет [f() for f in [lambda: i for i in range(3)]]?

Разбор

Образцовый ответ: «Замыкание это вложенная функция, которая использует имена из охватывающей функции и сохраняет к ним доступ после того, как внешняя функция вернула результат. CPython кладёт такие переменные в объекты-ячейки, и у вложенной функции есть __closure__ с этими ячейками. Важно, что сохраняется связь с переменной, а не снимок значения, поэтому если переменная потом изменится, функция увидит новое значение. Отсюда ловушка: список лямбд, созданных в цикле, при вызове вернёт последнее значение счётчика для всех. Лечится аргументом по умолчанию lambda i=i: i или functools.partial. Читать переменную внешней функции можно свободно, а чтобы присвоить ей новое значение, нужно объявить nonlocal, иначе имя станет локальным и будет UnboundLocalError. global в отличие от него ссылается на уровень модуля. На замыканиях построены декораторы, фабрики функций, обработчики с контекстом. Когда состояния много или нужны несколько методов, читабельнее сделать класс».

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

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