← Назад к вопросам
Как называются переменные вне функции, с точки зрения Scope?
1.3 Junior🔥 261 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Scope переменных в Python (LEGB правило)
Переменные вне функции называются глобальными (Global scope), но это только одна часть системы видимости в Python. Полная иерархия scope называется LEGB правилом.
LEGB: Порядок поиска переменных
При обращении к переменной Python ищет её в следующем порядке:
L — Local (локальный scope функции)
E — Enclosing (замыкание — внешняя функция)
G — Global (глобальный scope модуля)
B — Built-in (встроенные переменные Python)
1. Local (L) — Локальный scope
Переменные, определённые внутри функции:
def foo():
x = 10 # Local scope
print(x) # 10
foo()
print(x) # NameError: x не определена
2. Enclosing (E) — Scope замыкания
Переменные из внешней функции (вложенные функции):
def outer():
x = 10 # Enclosing scope для inner
def inner():
print(x) # 10 (ищет в Enclosing)
inner()
outer()
Цепочка поиска:
def outer():
x = "outer"
def middle():
x = "middle"
def inner():
x = "inner"
print(x) # inner (Local)
inner()
print(x) # middle (Local для middle)
middle()
print(x) # outer (Local для outer)
outer()
3. Global (G) — Глобальный scope
Переменные на уровне модуля (вне функций и классов):
x = 100 # Global scope
def foo():
print(x) # 100 (ищет в Global)
foo()
4. Built-in (B) — Встроенные имена
Встроенные функции и типы Python:
print(len) # <built-in function len>
print(int) # <class int>
print(True) # True
# Это встроенные имена в scope B
Полный пример LEGB
x = "Global" # G
def outer(param):
x = "Enclosing" # E
def inner():
x = "Local" # L
y = param # E (параметр — тоже Enclosing для inner)
z = len([1, 2, 3]) # B (встроенная функция len)
print(f"L: {x}, E: {y}, G: найдена при нужде, B: {z}")
inner()
outer("param_value")
# L: Local, E: param_value, G: найдена при нужде, B: 3
Проверка scope с помощью globals() и locals()
x = "global"
def foo():
y = "local"
print(locals()) # {"y": "local"}
print(globals()) # Очень большой словарь со всеми глобальными переменными
foo()
Функция vars() для class
class MyClass:
class_var = "class"
def __init__(self):
self.instance_var = "instance"
obj = MyClass()
print(vars(obj)) # {"instance_var": "instance"}
print(vars(MyClass)) # Очень много, включая class_var
dir() — все имена в scope
def foo():
x = 10
print(dir()) # Список всех доступных имён
foo()
Конфликты и приоритет
Если переменная определена в нескольких scope, используется первая найденная по LEGB:
x = "Global"
def outer():
x = "Enclosing"
def inner():
x = "Local"
print(x) # "Local" (L первый в LEGB)
inner()
outer()
Ключевые слова: global и nonlocal
global — обращение к Global scope:
x = 0
def increment():
global x # Теперь x относится к Global scope
x += 1
increment()
print(x) # 1
nonlocal — обращение к Enclosing scope:
def outer():
x = 0
def inner():
nonlocal x # Теперь x относится к Enclosing scope
x += 1
inner()
print(x) # 1
outer()
Задача на понимание LEGB
a = "A"
def level1():
a = "L1"
def level2():
a = "L2"
def level3():
print(a) # Что выведется?
level3()
level2()
level1()
# Ответ: L2 (используется ближайший scope)
Без явного определения в Local
a = "Global"
def foo():
print(a) # "Global" (ищет в Enclosing, потом Global)
foo()
Когда это становится сложным
g = "global"
def outer():
e = "enclosing"
def inner():
# Если мы хотим читать из разных scope:
print(g) # "global" — читаем из G
print(e) # "enclosing" — читаем из E
# Но если мы хотим ПИСАТЬ в них:
# g = "new" # Создаст новый L (не Global!)
# global g # Нужно явно указать
# e = "new" # Создаст новый L (не Enclosing!)
# nonlocal e # Нужно явно указать
inner()
outer()
Инспекция scope
import inspect
def outer():
x = 10
def inner():
print(inspect.currentframe().f_locals) # Local scope
print(inspect.currentframe().f_globals) # Global scope
inner()
outer()
Резюме
- Global scope — переменные вне функций
- Local scope — внутри функции
- Enclosing scope — во вложенных функциях
- Built-in scope — встроенные имена
- LEGB правило определяет порядок поиска
- global/nonlocal для явной работы с другими scope
Понимание scope критично для избегания ошибок и написания предсказуемого кода.