10.1 Локальные переменные функции
В Python переменная доступна (к ней можно обращаться) с момента своего создания и до конца своей области видимости — чаще всего это функция, в которой она объявлена. Если переменная объявлена вне всех функций, то она называется глобальной.
В Python области видимости переменных определяют контекст, в котором переменные доступны для использования. Области видимости помогают избежать конфликтов имён и управлять доступом к данным. Основные типы областей видимости в Python включают:
Локальная область видимости: Переменные, созданные внутри функции, существуют в локальной области видимости этой функции и доступны только внутри неё.
Область видимости вложенных функций: Если функция определена внутри другой функции, её переменные доступны только внутри этой вложенной функции.
Глобальная область видимости: Переменные, определённые на уровне скрипта или модуля, считаются глобальными и доступны из любой части кода в том же модуле.
Встроенная область видимости: Это специальная область видимости, которая включает в себя все встроенные объекты и функции Python, доступные по умолчанию (например, print() и len()).
Правило LEGB
Для разрешения переменных Python использует правило LEGB, которое определяет порядок, в котором интерпретатор ищет переменные:
- L (Local) — Сначала поиск в локальной области видимости.
- E (Enclosed) — Затем в областях видимости всех вложенных функций, от ближайшей к внешней.
- G (Global) — Далее в глобальной области видимости.
- B (Built-in) — Наконец, во встроенной области видимости.
Примеры использования
x = "global" # Глобальная переменная
def outer():
y = "outer local" # Локальная переменная внешней функции
def inner():
z = "inner local" # Локальная переменная вложенной функции
print(x) # Выводит "global"
print(y) # Выводит "outer local"
print(z) # Выводит "inner local"
inner()
outer()
Переменная z доступна только внутри функции inner().
Переменная y доступна внутри функции outer() и во всех функциях, объявленных внутри неё.
Переменная x доступна везде в текущем файле (модуле).
10.2 Доступ к глобальным переменным: global x
Интересной особенностью языка Python является то, что переменные из внешних областей видимости (в которые вложена текущая область видимости) можно только читать.
При попытке записать что-то во внешнюю переменную будет создана локальная переменная с таким же именем, а доступ к внешней переменной будет потерян.
Пример:
x = 10
def change_global():
print(x) # Это вызовет ошибку, так как x будет считаться локальной переменной после присвоения
x = 20 # Тут создастся локальная переменная x
print(x) # Выведет 20 (идёт обращение к локальной переменной x)
change_global()
print(x) # Выведет 10
Этот пример не работает и вызовет ошибку UnboundLocalError, потому что интерпретатор Python сначала видит присвоение x = 20 и считает, что x является локальной переменной. Однако, когда интерпретатор доходит до строки print(x), он не находит локальной переменной x, так как она ещё не была определена.
Так сделано для безопасности, чтобы локальные переменные случайно не изменили глобальные.
Оператор global
Если вам нужно осознанно изменить значение глобальной переменной внутри функции, для этого можно использовать оператор global. Этот оператор позволяет явно указать, что изменение должно произойти именно в глобальной переменной, а не в локальной.
Чтобы изменить значение глобальной переменной внутри функции, необходимо объявить эту переменную в начале функции с помощью global. Это даёт функции доступ на запись к переменной:
x = 10
def change_global():
global x # Объявляем x как глобальную переменную
print(x) # Выведет 10 (идёт обращение к глобальной переменной x)
x = 20 # Тут присваиваем новое значение глобальной переменной x
print(x) # Выведет 20 (идёт обращение к глобальной переменной x)
change_global()
print(x) # Выведет 20
Использование оператора global позволяет избежать ошибки и правильно управлять глобальными переменными.
Глобальные переменные могут сделать программу менее предсказуемой и труднее для понимания, так как их значения могут быть изменены в любом месте программы. Это особенно критично, если программа большая и разрабатывается группой программистов.
Хотя иногда использование глобальных переменных неизбежно, лучше стараться минимизировать их применение. Вместо глобальных переменных рассмотрите возможность использования параметров функций, возвращаемых значений и классов для хранения состояния.
Использование глобальных переменных может привести к неожиданным побочным эффектам, затруднить отладку и тестирование кода, а также снизить его переиспользуемость. Поэтому рекомендуется использовать глобальные переменные с осторожностью и только когда это действительно необходимо.
10.3 Доступ к не-локальным переменным: nonlocal
Кроме глобальных и локальных переменных, в Python существуют переменные из промежуточных областей видимости. Например, когда функция вложена в другую функцию. Для работы с такими переменными используется оператор nonlocal.
Оператор nonlocal позволяет работать с переменными во вложенных функциях, изменяя их значения в ближайшей области видимости, исключая глобальные переменные.
Оператор nonlocal помогает избежать создания новой локальной переменной во вложенной функции, когда необходимо изменить переменную, определённую во внешней функции. Без использования nonlocal изменения затронут только локальную переменную внутренней функции, не влияя на переменную во внешней функции.
Пример:
def outer():
count = 0
def inner():
nonlocal count
count += 1
return count
return inner
counter = outer()
print(counter()) # Выведет 1
Вот более практический пример использования nonlocal для создания счётчика:
def create_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = create_counter()
print(counter()) # Выведет 1
print(counter()) # Выведет 2
print(counter()) # Выведет 3
Этот пример демонстрирует, как nonlocal может быть использован в реальных сценариях для создания функции, которая сохраняет своё состояние между вызовами.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ