Теория урока

56. Замыкания и оператор nonlocal в Python

В предыдущем уроке мы разобрались с областью видимости в Python. Сейчас будем разбираться с замыканиями. Тема достаточно непростая для понимания начинающему программисту. Если вы дошли до этого урока, то обязательно разберетесь с замыканиями, не сомневайтесь.

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

Внутренняя функция создается при каждом выполнении внешней. Таким образом, каждый раз создается новый экземпляр с обновленными ссылками на переменные внешней функции. Эти ссылки действительны до тех пор, пока выполняется вложенная функция.

Согласен, немного непонятно, поэтому рассмотрим пример:

Пример
def mult(num1):
def inner(num2):
return num1 * num2
return inner

mult_by_2 = mult(2) # ссылается на inner()
print(mult_by_2(2)) # => 4

В данном примере функция inner() является замыканием. Так же необходимо понимать в какой момент происходит запоминание значения. Для этого рассмотрим пример:

Пример
def mult(num1):
x = 1
def inner(num2):
return num1 * num2 + x
x = 10
return inner
mult_by_2 = mult(2)
print(mult_by_2(2))

На первый взгляд можно предположить, что результатом будет число 5, но нет.

Рассмотрим следующий пример:

Пример
def mult(num1):
a = 10
def inner(num2):
a += 1
return num1 * num2 + a
return inner

mult_by_2 = mult(2)
print(mult_by_2(2))

Выполнение этого кода вызовет ошибку. Переменная a является свободной, поэтому чтобы ее менять с сохранением измененного значения между вызовами, следует использовать nonlocal:

Пример
def mult(num1):
a = 10
def inner(num2):
nonlocal a
a += 1
return num1 * num2 + a
return inner

Для обыкновенного присваивания значения переменной a, nonlocal использовать не нужно. Например, nonlocal можно использовать следующим способом:

Пример
def up(num1):
a = num1
def inner():
nonlocal a
a -= 1
return a
return inner

up_one = up(10)
print(up_one()) # => 9
print(up_one()) # => 8
print(up_one()) # => 7
print(up_one()) # => 6

Замыкания из-за умения запоминать значения свободных переменных чем-то напоминают классы (о них мы будем говорить позднее). Далее пример:

Пример
def calc(a, b):
def add():
return a + b
def sub():
return a - b

calc.add = add
calc.sub = sub
return calc

calc_obj = calc(10, 2)
print(calc_obj.add()) # => 12
print(calc_obj.sub()) # => 8

В этом уроке познакомились с замыканиями в Python и ситуациями, когда следует использовать оператор nonlocal. Далее будем говорить об аргументах функции.

ПРОЧИТАНО
Следующий урок

Похожие уроки и записи блога

Продолжаем написание классов в PythonЗнакомство с Python
Написание модулей в PythonЗнакомство с Python
Аргументы и параметры функций, операторы * и ** в PythonЗнакомство с Python
Типы данных в PythonЗнакомство с Python
Еще о возможностях модулей в Python Знакомство с Python
Основы функций в PythonЗнакомство с Python
Более глубокое изучение классов в PythonЗнакомство с Python
Функциональное программирование: map, filter и reduceЗнакомство с Python
Модули в PythonЗнакомство с Python
<
×
>
Впервые на сайте Codebra?

Извините за это всплывающее окно, меня они тоже раздражают.

Образовательный ресурс codebra.ru полностью посвящен программированию. Все курсы и уроки находятся на главной странице. Ради интереса можете посмотреть на содержимое курсов по Python, HTML и CSS, JavaScript, C++ и другие, размещенные на главной странице.

Если что-то не нашли, то воспользуйтесь поиском по сайту, который находится на главной странице в самом верху.

Удачи в обучении!

Закрыть окно