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

Как в Python происходит поиск переменной по областям видимости?

1.0 Junior🔥 241 комментариев
#Python Core

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

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

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

Правило LEGB в Python

Поиск переменной в Python происходит по правилу LEGB — это аббревиатура четырех уровней область видимости, где Python ищет переменную в строгом порядке:

  1. L (Local) — локальная область функции
  2. E (Enclosing) — область охватывающей функции
  3. G (Global) — глобальная область модуля
  4. 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.