← Назад к вопросам
Как в Python происходит поиск переменной по областям видимости?
1.0 Junior🔥 241 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Правило LEGB в Python
Поиск переменной в Python происходит по правилу LEGB — это аббревиатура четырех уровней область видимости, где Python ищет переменную в строгом порядке:
- L (Local) — локальная область функции
- E (Enclosing) — область охватывающей функции
- G (Global) — глобальная область модуля
- B (Built-in) — встроенные функции Python
Визуальный пример:
# B — встроенное значение
print(len)
# G — глобальная переменная
x = "global"
def outer():
# E — переменная охватывающей функции
y = "enclosing"
def inner():
# L — локальная переменная
z = "local"
print(z) # ищет в L найдена
print(y) # ищет в L не найдена ищет в E найдена
print(x) # ищет везде найдена в G
print(len) # ищет везде найдена в B
inner()
outer()
Детальный механизм поиска:
def level1():
var = "L1"
def level2():
var = "L2"
def level3():
print(var) # Выведет L2
level3()
level2()
level1()
Важные нюансы с nonlocal и global:
Проблема без nonlocal:
def outer():
x = 10
def inner():
x = 20
print(x) # 20
inner()
print(x) # 10 не изменилась
Решение с nonlocal:
def outer():
x = 10
def inner():
nonlocal x
x = 20
print(x) # 20
inner()
print(x) # 20 изменилась
То же с global:
x = "global"
def modify_global():
global x
x = "modified"
modify_global()
print(x) # modified
Как Python определяет тип переменной при компиляции:
def func():
print(x) # UnboundLocalError
x = 5
func()
Почему ошибка? Потому что Python при компиляции видит x = 5 → помечает x как локальную для этой функции.
Проверка scope переменной:
global_var = "I am global"
def check_scope():
local_var = "I am local"
print("locals():", locals())
print("globals().keys():", list(globals().keys()))
def inner():
print("inner locals:", locals())
print("can access:", local_var)
inner()
check_scope()
Практический пример:
class Config:
timeout = 30
timeout = 10
def api_call():
timeout = 5
def retry_logic():
attempts = 0
while attempts < timeout:
attempts += 1
retry_logic()
print(Config.timeout)
api_call()
Схема поиска:
Основной принцип: Python ищет переменную изнутри наружу. Первая найденная переменная используется. Это создает эффект затенения переменных из внешних scope.