Ключевое слово nonlocal в Python

В Python вы в основном имеете дело с двумя типами переменных:

  • Глобальными (объявленными вне тела функции, то есть в глобальной области видимости)
  • Локальными (объявленными внутри функции, то есть в локальной области видимости)

Но когда функция находится внутри другой функции, переменные внешней функции с ее точки зрения не являются ни локальными, ни глобальными. Такие переменные в Python называются нелокальными переменными.

Если вам нужно работать с нелокальной переменной в Python, вы должны использовать ключевое слово nonlocal. Другими словами, nonlocal используется, если вам нужно получить доступ к переменной внешней функции из внутренней функции.

В этом руководстве мы на примерах разберем, как работает ключевое слово nonlocal. Но прежде чем перейти к основной теме, стоит вкратце рассказать об областях видимости в Python.

Области видимости в Python

Схема областей видимости в Python
  1. Переменная, находящаяся внутри функции, принадлежит локальной области видимости функции. Никакие другие части кода не могут получить доступ к этой переменной, кроме тех, что находятся внутри данной функции.
  2. Функция внутри функции имеет свою локальную область видимости, а также область видимости внешней функции. Последняя называется нелокальной областью видимости.
  3. Глобальная область видимости – это область видимости “по умолчанию” в Python. Все, что находится вне функции, относится к глобальной области видимости.
  4. Встроенная область видимости – это самая широкая область видимости из всех существующих. Она управляет даже глобальной областью. Встроенная область видимости доступна везде. Например, все ключевые слова Python находятся во встроенной области видимости и могут быть использованы в любой части вашего кода.

Вложенные функции в Python

В Python функции можно размещать внутри других функций. Такие функции называются вложенными. При работе со вложенными функциями важно понимать, как изменяется область видимости.

В обычной функции все, что находится внутри функции, относится к локальной области видимости. А все, что находится снаружи, относится к глобальной области видимости.

Но когда функция находится внутри другой функции, внутренняя функция видит свою локальную область видимости, окружающую область видимости внешней функции (нелокальную область видимости) и глобальную область видимости.

Пример 1. Простая вложенная функция

def outer():
    print("Outer function")
    def inner():
        print("Inner function")
    inner()

outer()

Вывод:

Outer function
Inner function

Это пример вложенной функции, в которой функция inner() управляется функцией outer().

Как правило, вложенные функции пригодятся вам там, где вы хотите создать функцию, недоступную глобально. В приведенном выше примере вызов функции inner() невозможен нигде в коде, кроме как внутри функции outer().

Функции outer() и inner() имеют доступ к глобальной и встроенной области видимости, а также к своим локальным областям. Кроме того, функция inner() имеет доступ к окружающей ее области видимости, то есть к области видимости функции outer().

С точки зрения функции inner() область видимости функции outer() не является ни глобальной, ни локальной. Именно поэтому в Python эта область называется нелокальной областью.

Пример 2. Поиск переменных в управляющих областях видимости

Чтобы лучше представить себе области видимости вложенных функций, давайте немного изменим приведенный выше пример:

def outer():
    text = "Outer function"
    print(text)
    def inner():
        print(text)
    inner()

outer()

Вывод:

Outer function
Outer function

Теперь при выполнении функции inner() Python не находит переменную text в локальной области видимости функции inner(), поскольку она там не определена. Поэтому Python проверяет окружающую область видимости функции inner() (нелокальную область видимости), чтобы узнать, есть ли там переменная text. Найдя ее, Python печатает нелокальную переменную text в вызове функции inner().

Ключевым моментом здесь является то, что если Python не находит переменную в текущей области видимости, он будет искать ее в родительской, начиная с локальной области видимости и заканчивая встроенной областью видимости.

Ключевое слово nonlocal

Если во вложенной функции есть переменная с тем же именем, что и в объемлющей функции, и вы хотите получить к ней доступ, вам нужно использовать ключевое слово nonlocal.

Этим вы даете понять интерпретатору Python, что обращаетесь не к переменной в локальной области видимости, а к переменной в объемлющей функции.

Например, вот вложенная функция bar(), которая находится внутри функции foo(). Обе функции объявляют переменную name. Чтобы получить доступ к переменной name функции foo() внутри функции bar(), необходимо использовать ключевое слово nonlocal:

def foo():
    name = "Alice"
    
    def bar():
        # Overwrite the name="Alice" variable
        nonlocal name
        name = "Bob"
        print(name)
    
    # Call the inner function bar()
    bar()
    
    # Print foo()'s local variable name
    print(name)

foo()

Вывод:

Bob
Bob

Таким образом, ключевое слово nonlocal сообщает Python, что вы обращаетесь к переменным объемлющей функции, а не к локальным переменным.

Заключение

Сегодня вы узнали, что такое ключевое слово nonlocal в Python и как его можно использовать.

Ключевое слово nonlocal ссылается на переменные в родительской области видимости. Использование nonlocal полезно, если вы хотите получить доступ к переменной родительской области видимости во вложенной функции.

Спасибо за прочтение. Успешного кодинга!

Перевод статьи Artturi Jalli “Python ‘nonlocal’ Keyword: A Complete Guide (Examples)”.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *