Что такое замыкание (closure) в Python и как оно работает

Ответ

Замыкание (closure) — это функция, которая "помнит" и имеет доступ к переменным из своей лексической области видимости, даже когда исполнение этой области завершено.

Как это работает:

Когда вложенная функция ссылается на переменную из внешней функции (не являющуюся её локальной переменной), Python связывает эту переменную с вложенной функцией. Эта связь сохраняется в специальном атрибуте __closure__.

Три условия для создания замыкания:

  1. Должна существовать вложенная функция.
  2. Вложенная функция должна ссылаться на переменные из внешней функции (так называемые "свободные переменные").
  3. Внешняя функция должна возвращать вложенную функцию.

Пример:

def outer_func(text):
    # 'text' - это свободная переменная для inner_func
    def inner_func():
        # inner_func "замыкает" в себе переменную text
        print(text)

    return inner_func

# Вызываем внешнюю функцию, она завершает работу,
# но возвращенная inner_func все еще помнит 'text'
printer_hello = outer_func("Hello")
printer_world = outer_func("World")

# Вызываем экземпляры вложенной функции
printer_hello()  # Вывод: Hello
printer_world()  # Вывод: World

# Можно проверить содержимое __closure__
# Это кортеж из объектов-ячеек (cell), хранящих значения
print(printer_hello.__closure__[0].cell_contents) # Вывод: Hello

Практическое применение:

  • Декораторы: Являются самым частым и ярким примером использования замыканий.
  • Фабрики функций: Создание функций с предопределенной конфигурацией (как в примере выше).
  • Сохранение состояния: Реализация объектов с состоянием без использования классов, например, для создания счетчиков или кэширования.