Области видимости (Scopes) в Python
Области видимости (Scopes) в Python
Определение
Область видимости (Scope) — это область кода, в которой переменная может быть использована. Python использует правило LEGB для поиска переменных:
- L (Local): Внутри функции.
- E (Enclosing): Внешние функции (для вложенных функций).
- G (Global): На уровне модуля.
- B (Built-in): Встроенные имена (например,
print,len).
Правило LEGB
Python ищет переменные в следующем порядке:
x = "global" # Global
def outer():
x = "enclosing" # Enclosing
def inner():
x = "local" # Local
print(x) # "local" (Local)
inner()
outer()
print(x) # "global" (Global)
print(len) # <built-in function len> (Built-in)
Ключевые слова global и nonlocal
global
Позволяет изменять глобальные переменные внутри функции.
x = 0
def change_global():
global x
x = 10 # Изменяет глобальную переменную
change_global()
print(x) # 10
nonlocal
Используется во вложенных функциях для изменения переменных из внешней области.
def outer():
x = 0
def inner():
nonlocal x
x = 20 # Изменяет переменную из outer()
inner()
print(x) # 20
outer()
Замыкания (Closures)
Вложенная функция “запоминает” переменные из внешней области видимости.
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
c = counter()
print(c()) # 1
print(c()) # 2 (сохраняет состояние count)
Функции globals() и locals()
- globals(): Возвращает словарь глобальных переменных.
- locals(): Возвращает словарь локальных переменных.
Можно ли их изменять?
globals(): Да (но осторожно!).locals(): Нет (изменения могут не отразиться на реальных переменных).
def test():
x = 10
locals_dict = locals()
locals_dict["x"] = 20 # Не изменит реальную x
print(x) # 10
test()
globals()["x"] = 30 # Изменит глобальную переменную
Область видимости переменных исключений
Переменная исключения (например, e в except Exception as e) существует только внутри блока except.
try:
1 / 0
except ZeroDivisionError as e:
print(e) # Работает
print(e) # NameError: name 'e' is not defined (в Python 3)
Исключение: Если переменная сохранена вне блока.
error = None
try:
1 / 0
except ZeroDivisionError as e:
error = e
print(error) # division by zero
Примеры частых ошибок
1. Создание локальной переменной вместо изменения глобальной
x = 10
def func():
x = 20 # Создает локальную переменную
print(x) # 20
func()
print(x) # 10 (глобальная не изменилась)
2. Использование nonlocal без внешней переменной
def outer():
def inner():
nonlocal x # SyntaxError: no binding for nonlocal 'x' found
x = 10
inner()
Заключение
- LEGB определяет порядок поиска переменных.
globalиnonlocalпозволяют изменять переменные из внешних областей.- Замыкания сохраняют состояние внешних переменных.
globals()иlocals()дают доступ к переменным, но изменять их нужно осторожно.- Переменные исключений недоступны вне блока
except.
Совет: Избегайте изменения глобальных переменных через global — это усложняет отладку. Используйте возвращаемые значения и параметры функций.