В Python вы в основном имеете дело с двумя типами переменных:
- Глобальными (объявленными вне тела функции, то есть в глобальной области видимости)
- Локальными (объявленными внутри функции, то есть в локальной области видимости)
Но когда функция находится внутри другой функции, переменные внешней функции с ее точки зрения не являются ни локальными, ни глобальными. Такие переменные в Python называются нелокальными переменными.
Если вам нужно работать с нелокальной переменной в Python, вы должны использовать ключевое слово nonlocal. Другими словами, nonlocal
используется, если вам нужно получить доступ к переменной внешней функции из внутренней функции.
В этом руководстве мы на примерах разберем, как работает ключевое слово nonlocal. Но прежде чем перейти к основной теме, стоит вкратце рассказать об областях видимости в Python.
Области видимости в Python
- Переменная, находящаяся внутри функции, принадлежит локальной области видимости функции. Никакие другие части кода не могут получить доступ к этой переменной, кроме тех, что находятся внутри данной функции.
- Функция внутри функции имеет свою локальную область видимости, а также область видимости внешней функции. Последняя называется нелокальной областью видимости.
- Глобальная область видимости – это область видимости “по умолчанию” в Python. Все, что находится вне функции, относится к глобальной области видимости.
- Встроенная область видимости – это самая широкая область видимости из всех существующих. Она управляет даже глобальной областью. Встроенная область видимости доступна везде. Например, все ключевые слова 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)”.