Краткий взгляд на замыкание
Давайте начнем с определения: замыкание - это метод, который позволяет хранить значения, несмотря на то, что контекст, в котором они были созданы, больше не существует. Запутанно? Немного.
Давайте проанализируем простой пример:
def outer(par):
loc = par
var = 1
outer(var)
print(var)
print(loc)
Пример явно ошибочный.
Последние две строки вызовут исключение NameError - ни par
, ни loc
недоступны вне функции. Обе переменные существуют тогда и только тогда, когда выполняется функция outer()
.
Посмотрите на пример в редакторе. Мы значительно изменили код.
В нем есть новый элемент - функция (с именем inner
) внутри другой функции (с именем external
).
Как это работает? Как и любая другая функция, за исключением того факта, что inner()
может вызываться только из outer()
. Мы можем сказать, что inner()
является частным инструментом external()
- никакая другая часть кода не может получить к нему доступ.
Посмотрите внимательно:
- функция
inner()
возвращает значение переменной, доступной внутри своей области видимости, так какinner()
может использовать любые объекты в распоряженииouter()
; - функция
external()
возвращает саму функциюinner()
; точнее, он возвращает копию функцииinner()
, которая была заморожена в момент вызоваexternal()
; замороженная функция содержит полное окружение, включая состояние всех локальных переменных, что также означает, что значениеloc
успешно сохранено, хотяouter()
перестала существовать давным-давно.
По сути, код полностью корректен и выводит:
1
output
Функция, возвращаемая во время вызова external()
, является замыканием.