Глава 13 · Автоматизация с помощью функций
Глобальные и локальные переменные
Где «живёт» переменная и в каком порядке Python её ищет — модель LEGB избавит от многих загадочных ошибок.
Переменные внутри функций
Переменная, созданная внутри функции, называется локальной — она существует только пока функция выполняется и недоступна снаружи:
lokalnye_peremennye.py
def moya_funkciya():
message = "Я живу только внутри функции"
print(message)
moya_funkciya()
print(message) # NameError: message не определена здесь
Глобальные переменные
Глобальная переменная объявлена вне всех функций — и доступна для чтения внутри любой из них:
globalnye_peremennye.py
course_name = "Python"
def lesson():
topic = "Функции"
print(course_name) # чтение глобальной — работает без всяких оговорок
print(topic)
lesson()
Функция может смотреть наружу, но не наоборот
Функция может ЧИТАТЬ глобальные имена, но переменные, созданные внутри неё, не становятся автоматически видны снаружи.
Затенение (shadowing)
shadowing.py
name = "GLOBAL"
def demo():
name = "LOCAL"
print(name)
demo()
print(name)
LOCAL
GLOBAL
Локальное имя затеняет глобальное с тем же именем
Внутри
demo() создаётся СВОЁ, отдельное локальное имя name — оно временно «заслоняет» глобальное name для кода внутри функции, но не заменяет и не удаляет его.LEGB: как Python ищет имя
Когда Python встречает имя, он ищет его по чёткому порядку — эту модель называют LEGB:
| Буква | Что это | Пример |
|---|---|---|
| L — Local | имена внутри текущей функции | topic внутри lesson() |
| E — Enclosing | имена внешней функции для вложенной (§13.13) | рассмотрим дальше |
| G — Global | имена на уровне модуля | course_name |
| B — Builtins | встроенные имена Python | len, print |
UnboundLocalError — почему это НЕ случайность
unbound_local.py
count = 10
def increment():
count += 1
increment()
Присваивание где-либо в теле делает имя локальным ВО ВСЁМ теле функции
Python видит
count += 1 (это count = count + 1) и заранее решает: раз count присваивается внутри функции, значит, это ЛОКАЛЬНОЕ имя — на протяжении ВСЕГО тела функции, а не только после присваивания. Но правая часть count + 1 пытается ПРОЧИТАТЬ count ДО того, как локальное значение вообще появилось — отсюда UnboundLocalError. Это не случайное поведение, а прямое следствие того, как Python заранее размечает локальные имена функции.global — если действительно нужно изменить глобальную переменную
global_keyword.py
count = 10
def increment():
global count
count += 1
increment()
print(count) # 11
global нужен только для присваивания, не для чтения
Просто ПРОЧИТАТЬ глобальную переменную можно без
global (мы это уже делали с course_name выше). global нужен, только когда функция собирается ИЗМЕНИТЬ (присвоить) глобальное имя.global работает, но чаще есть способ лучше
global — не запрещённая, но зачастую не лучшая практика: функции, которые читают параметры и возвращают результат через return, легче тестировать и переиспользовать, потому что их поведение не зависит от скрытого внешнего состояния. Это не абсолютное правило «глобальные переменные — всегда плохо» — иногда общее состояние действительно уместно, — но по умолчанию стоит предпочитать параметры и return.Практика: локальные, глобальные переменные и LEGB
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки