Теория урока

13.5. Замыкания и оператор 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. Далее будем говорить об аргументах функции.

ПРОЧИТАНО
Следующий урок
<
×
>
Впервые на сайте Codebra?

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

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

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

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

Закрыть окно