Что такое замыкание в Python
Что проверяют
Для тестировщика это вопрос не про теорию языка, а про происхождение двух частых дефектов автотестов: параметризованные проверки, которые все смотрят на один и тот же случай, и прогоны, где память растёт от файла к файлу. Ждут, что вы объясните механизм, а не процитируете определение.
Как отвечать
Замыкание это вложенная функция, которая продолжает пользоваться переменными объемлющей области после того, как та завершилась. Важная деталь: Python хранит такие переменные в ячейках и захватывает саму переменную, а не её значение на момент создания функции.
В автотестах это ежедневный инструмент: фабрики проверок, декораторы повтора и таймаутов, колбэки ожиданий, генераторы тестовых данных.
def has_status(expected):
def check(response):
return response.status_code == expected
return checkГлавное практическое следствие это позднее связывание: функция берёт значение переменной в момент вызова, а не в момент создания.
checks = [lambda: title == t for t in titles] # все увидят последний t
checks = [lambda t=t: title == t for t in titles] # значение зафиксированоЧтобы менять захваченную переменную, нужен nonlocal, иначе присваивание создаст новую локальную переменную внутри вложенной функции.
Где спотыкаются
Собирают проверки в цикле и получают набор кейсов, которые все дёргают последний параметр. Отчёт зелёный, а проверено одно значение из десяти. В pytest такие наборы делаются параметризацией, а не самодельным циклом с лямбдами.
Считают замыкание способом спрятать состояние. Содержимое ячейки достаётся из атрибута функции в одну строку, так что это не приватность, а всего лишь отсутствие удобного имени снаружи.
Удерживают в замыкании драйвер, сессию или крупный ответ и удивляются росту памяти в длинном прогоне. Ссылка жива, пока жива функция, а функция, привязанная к фикстуре уровня модуля, живёт весь файл тестов.