- 6 августа 2025
- 6 минут
- 291
Области видимости переменных и принципы их формирования в Python
Статью подготовили специалисты образовательного сервиса Zaochnik.
Имя переменной и операция присваивания
Каждый раз, при использовании программой некоего имени, интерпретатор создает, вносит изменение или ищет его в пространстве имен.
Под областью видимости понимается пространство имен для определенного идентификатора (имени).
В Python область видимости обусловлена операциями присваивания.
Возникновение имен происходит в тот момент, когда им в первый раз присваиваются значения, и они должны получить значение, прежде чем могут быть использованы. Так как имена не требуют предварительного объявления, интерпретатор Python ассоциирует имя со строго определенным пространством имен, основываясь на месте операции присваивания. Локация, где происходит присвоение, определяет пространство имен, к которому принадлежит имя, и, соответственно, область его видимости.
По дефолту все имена, которые получают значения внутри функции, относятся к пространству имен этой функции. Это подразумевает, что:
- Имена, объявленные в рамках инструкции `def`, доступны только внутри этой инструкции. К ним невозможно обратиться за границами функции.
- Имена, созданные внутри `def`, не конфликтуют с именами, находящимися вне функции, даже если там используются одинаковые наименования. Имя `X`, которому присвоено значение вне настоящей инструкции (`def`) (к примеру, в другой функции или внутри модуля), полностью отличается от имени `X`, имеющего значение внутри `def`.
- Область видимости переменной (где она может быть использована) всегда предписывается местом, где произошло присвоение ей значения, а не тем местом, откуда была вызвана функция или произведена операция изменения объекта.
Переменным можно присваивать значения в трех различных местах, что соответствует трем различным областям видимости:
- Если значение переменной присваивается внутри инструкции `def`, такая переменная представляет собой локальную переменную для этой функции.
- В случае, когда присваивание происходит в пределах родительской инструкции `def`, такая переменная имеет значение нелокальной для этой функции.
- Когда присваивание происходит вне всех инструкций `def`, такая переменная называется глобальной и выступает в данном качестве для всего файла.
Принципы формирования видимости имен
Код за пределами (вне) функций расположен на верхнем уровне модуля.
Функции формируют вложенные области видимости имен (пространства), которые в свою очередь ограничивают доступ к именам, используемым внутри них, благодаря чему имена в функциях и за их пределами (внутри модуля или других функций) не конфликтуют между собой .
Функции создают локальную область видимости, в то время как модули представляют глобальную область. Эти два уровня взаимодействуют согласно следующему принципу:
- При каждом вызове функции создается новая локальная область видимости.
- Процессом присвоения создаются локальные имена в случае, когда они не объявлены глобальными или нелокальными. Все имена, которым назначаются значения в функции, по умолчанию относятся к локальной области видимости (пространству имен, связанному с вызовом функции).
Последовательность сопоставления имен включает:
- локальные,
- нелокальные (внутри родительской инструкции `def`),
- глобальные (в пространстве имен модуля),
- встроенные (предопределенные имена из модуля `builtins`).
Схему разрешения имен в Python иногда называют правилом LEGB, где данная аббревиатура составлена из первых букв названия каждой области видимости.
Перекрытие областей видимости:
```python
X = 99
def func():
X = 88
```
Доступ на присваивание к нелокальным именам
Присваивания внутри функции классифицируют имена как локальные.
Если какая-либо из форм присваивания происходит в рамках инструкции `def`, имя становится локальным для этой функции. Чтобы присвоить значение имени верхнего уровня модуля, содержащего функцию, это имя должно быть объявлено глобальным с помощью инструкции `global`. Если необходимо присвоить значение имени, которое находится в родительской инструкции `def`, его нужно объявить как нелокальное с помощью инструкции `nonlocal`.
Операции непосредственного изменения объектов не классифицируют имена как локальные — это касается только операций присваивания. Например, если имени `L` присвоен список, определенный в пространстве верхнего уровня модуля, то операция `L.append(X)` внутри функции не сделает `L` локальным, тогда как `L = X` — будет являться локальным. В первом случае происходит изменение объекта списка, на который указывает `L`, а не самого имени `L`, — список `L` будет найден в глобальной области видимости, и Python изменит этот список без необходимости объявления имени `global` (или `nonlocal`). Этот пример иллюстрирует разницу между именами и объектами: изменение объекта отличается от присваивания объекта имени.
Инструкция `global` информирует интерпретатор о том, что функция будет изменять одно или более глобальных имен. `global` объявляет глобальные переменные без присваивания им значений.
```python
X = 88 # Глобальная переменная X
def func():
global X
X = 99 # Глобальная переменная X: вне инструкции def
func()
print(X) # Выведет 99
```
Таким образом, `global` позволяет изменять переменные модуля из функций. Существует также инструкция `nonlocal`, которая позволяет изменять переменные в родительских функциях.