Как называются переменные внутри функции, с точки зрения Scope?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Scope (область видимости) в Python
Scope определяет, где и как можно получить доступ к переменной. Python использует правило LEGB для поиска переменных.
Правило LEGB
Питон ищет переменную в этом порядке:
L — Local (локальная, внутри функции)
E — Enclosing (охватывающая, внешняя функция)
G — Global (глобальная, на уровне модуля)
B — Built-in (встроенная в Python)
1. Local (Локальная область)
Переменные, определённые внутри функции, видны только в этой функции.
def my_function():
x = 10 # Local переменная
y = 20 # Local переменная
print(x + y) # 30
my_function()
print(x) # NameError: name 'x' is not defined
Ключевая особенность:
- Переменная создаётся при входе в функцию
- Уничтожается при выходе из функции
- Видна только внутри этой функции
def outer():
x = "outer"
def inner():
y = "inner" # Local для inner()
print(y)
inner() # inner
print(y) # NameError: y не существует в outer
outer()
2. Enclosing (Охватывающая область)
Это область внешней функции, когда функция вложена внутрь другой функции.
def outer():
x = "I'm in outer" # Enclosing для inner()
def inner():
print(x) # Может читать x из outer
inner() # I'm in outer
outer()
Вложенные функции:
def level1():
a = 1 # Enclosing для level2
def level2():
b = 2 # Enclosing для level3, Local для level2
def level3():
c = 3 # Local для level3
print(a, b, c) # 1 2 3 (видны все три)
level3()
level2()
level1()
ВАЖНО: Enclosing vs Local
def outer():
x = "outer"
def inner():
x = "inner" # Это новая Local переменная, не переопределение outer.x!
print(x)
inner() # "inner"
print(x) # "outer" — outer.x не изменилась!
outer()
3. Global (Глобальная область)
Переменные на уровне модуля (вне функций и классов).
x = "I'm global" # Global переменная
def my_function():
print(x) # Может читать global переменную
my_function() # I'm global
Модификация global переменной:
counter = 0 # Global
def increment():
global counter # Указываем, что используем global переменную
counter += 1
increment()
increment()
print(counter) # 2
БЕЗ global:
counter = 0
def increment():
counter += 1 # ❌ UnboundLocalError!
# Python видит counter += 1 и определяет counter как Local
# Но читать Local можно только после присваивания
increment() # UnboundLocalError
4. Built-in (Встроенная область)
Встроенные функции и переменные Python (print, len, str, Exception и т.д.).
print(len([1, 2, 3])) # len() из Built-in
print(type("hello")) # type() из Built-in
print(ValueError) # ValueError из Built-in
# Но можно переопределить (плохая идея!)
len = lambda x: 999
print(len([1, 2, 3])) # 999 — переопределил Built-in!
Полный пример LEGB
# B — Built-in
print(type) # <class 'type'>
# G — Global
global_var = "GLOBAL"
def outer_function():
# E — Enclosing
enclosing_var = "ENCLOSING"
def inner_function():
# L — Local
local_var = "LOCAL"
# Поиск переменных в порядке LEGB
print(local_var) # L — находим в Local
print(enclosing_var) # E — находим в Enclosing
print(global_var) # G — находим в Global
print(type) # B — находим в Built-in
inner_function()
outer_function()
Случаи затеняния (Shadowing)
Переменные в близком scope затеняют переменные в дальнем scope.
x = "GLOBAL"
def outer():
x = "ENCLOSING" # Затеняет global x
def inner():
x = "LOCAL" # Затеняет enclosing x
print(x) # LOCAL
inner()
print(x) # ENCLOSING
outer()
print(x) # GLOBAL
Как получить доступ к затенённой переменной?
x = "GLOBAL"
def my_function():
x = "LOCAL"
# ❌ Не можем просто получить global x
# print(???) # Как достать GLOBAL?
# Нужно использовать модуль
import __main__
print(__main__.x) # GLOBAL
my_function()
nonlocal vs global
global — для модуль-уровня
count = 0
def increment():
global count
count += 1
increment()
print(count) # 1
nonlocal — для вложенных функций
def outer():
x = 0
def inner():
nonlocal x # Изменяем x из outer()
x += 1
inner()
print(x) # 1
outer()
nonlocal vs global:
# Global
global_x = 0
def func1():
global global_x
global_x += 1
# Nonlocal
def outer():
enclosing_x = 0
def func2():
nonlocal enclosing_x
enclosing_x += 1
func2()
return enclosing_x
Класс с методами
class MyClass:
class_var = "CLASS" # Класс переменная
def __init__(self):
self.instance_var = "INSTANCE" # Instance переменная
def method(self):
local_var = "LOCAL" # Local переменная
print(local_var) # LOCAL — поиск в Local → найдено
print(self.instance_var) # INSTANCE — через self
print(self.class_var) # CLASS — через self
print(MyClass.class_var) # CLASS — напрямую через класс
obj = MyClass()
obj.method()
Быстрая справка
# Global scope
x = 10
def outer():
# Enclosing scope
y = 20
def inner():
# Local scope
z = 30
print(z) # ✅ Local
print(y) # ✅ Enclosing (через closure)
print(x) # ✅ Global
print(len) # ✅ Built-in
inner()
outer()
Правила для запоминания
- Локальные переменные видны только внутри функции
- Вложенные функции могут читать переменные внешних функций (closure)
- Модификация требует ключевого слова:
globalилиnonlocal - Поиск идёт в порядке LEGB
- Ближний scope затеняет дальний
- Built-in можно переопределить, но это плохая идея
Понимание scope — фундамент для писания чистого и предсказуемого кода!