← Назад к вопросам

Как называются переменные внутри функции, с точки зрения Scope?

1.6 Junior🔥 171 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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()

Правила для запоминания

  1. Локальные переменные видны только внутри функции
  2. Вложенные функции могут читать переменные внешних функций (closure)
  3. Модификация требует ключевого слова: global или nonlocal
  4. Поиск идёт в порядке LEGB
  5. Ближний scope затеняет дальний
  6. Built-in можно переопределить, но это плохая идея

Понимание scope — фундамент для писания чистого и предсказуемого кода!

Как называются переменные внутри функции, с точки зрения Scope? | PrepBro