54. Область видимости в Python
Оглавление урока
- Самые основы областей видимости в Python
- Переопределение встроенных имен
- Оператор global
- Вложенная область видимости
В предыдущем уроке мы познакомились с основами функций в Python. Как вы поняли, создать собственную функцию на Python – очень просто. В этом уроке мы копнем чуть глубже, а именно, поговорим об области видимости переменных. Область видимости позволяет предотвратить конфликт имен в больших проектах, где их огромное количество.
Как вы поймете далее, место инициализации переменной в коде играет большую роль. Благодаря области видимости, вы можете, например, сохранять состояние между вызовами функций. С другой стороны, чрезмерное использование глобальных переменных может плохо сказаться на сопровождении кода.
Самые основы областей видимости в Python
Вообще, что такое область видимости в Python? То, где будет доступна переменная, это и есть область видимости. Интерпретатор Python ищет имена в соответствии с правилом LEGB. Например, если вы указываете какое-то имя, Python сначала будет искать его последовательно в локальной, вложенной, глобальной и встроенной области видимости. Это означает следующее: поиск имени осуществляется внутри функции (локальная область), далее внутри тех функций, в которых располагается наша функция (вложенная область), далее в скрипте (глобальная область) и в конце, если имя не было найдено ранее, в зарезервированных значениях Python (встроенная область).
Таким образом, имена, присвоенные внутри def
из предыдущего урока, видимы только внутри этого оператора. Рассмотрим пример:
A = 10
def local_A():
A = 20
print("Local", A)
local_A()
print("Global: ", A)
local_A()
Обратите внимание на вывод этой программы:
Local 20
Global: 10
Local 20
Мы инициализировали глобальную переменную A
числом 10
. В тоже время, в функции local_A()
, была инициализирована локальная (для функции) переменная с тем же именем, но числом 20
. Таким образом видно, что функции помогают избежать конфликт имен. Стоит понимать, локальная область видимости создается при каждом вызове функции и «пропадает» после завершения выполнения функции.
Переопределение встроенных имен
Так как интерпретатор Python использует правило LEGB, то как вы могли догадаться, внутри функции можно «случайно» переопределить встроенную функцию, например, print()
:
def redefinition():
print = "Hello"
print("World")
redefinition()
Таким образом, встроенная функция print()
была переопределена внутри функции redefinition()
.
Оператор global
В предыдущем уроке были перечислены операторы и выражения, которые используются для написания функций в Python. Одни из них был оператор global
. Этот оператор чем-то напоминает оператор объявления по аналогии с другими языками программирования. Оператор global
не объявляет тип или размер. Он задает пространство имен. Оператор global
сообщает об изменении какого-то глобального имени. Проще вернуться к примеру, и указать оператор global
перед локальной переменной A
:
A = 10
def local_A():
global A
A = 20
print("Local", A)
local_A()
print("Global: ", A)
local_A()
Обратите внимание, мы не просто приписали оператор global
к переменной A
. Следующая строка распознается интерпретатором как ошибочная:
global A = 20
Не забывайте о необходимости минимизировать количество глобальных имен, так как большое их количество может привести к ошибкам и к более трудному сопровождению кода. В то же время, глобальные переменные позволяют сохранять информацию о состоянии, которая будет использоваться в функции при повторном вызове.
Вложенная область видимости
Когда перечислялись существующие области видимости в Python, у вас мог возникнуть вопрос по поводу вложенной области видимости. Рассмотрим пример:
A = 10
def fl() :
A = 20
def f2():
print(A)
f2()
fl()
Здесь функция f2
является вложенной в f1
и запускается, пока выполняется последняя. Обратите внимание, функция f2
печатает переменную А
не глобальную, а вложенную или локальную для функции f1
. Теперь бы плавно перейти к замыканиям в Python. Но лучше оставим эту непростую тему до следующего урока.