Глава 13 · Автоматизация с помощью функций

Вложенные функции и nonlocal

Функция может быть определена прямо внутри другой функции — а nonlocal позволяет ей изменить имя из объемлющей функции, а не только прочитать его.

Функция внутри функции

Функцию можно определить прямо внутри тела другой функции:

vlozhennaya_funkciya.py
def outer():
    message = "Hello"

    def inner():
        print(message)

    inner()

outer()
inner видит message — это и есть Enclosing из LEGB
inner() не имеет своего message, но находит его в объемлющей функции outer() — это буква «E» (Enclosing) из ладдера LEGB (§13.12).
Отступ — это не украшение, а объявление вложенности
Если случайно сдвинуть def inner(): на уровень отступа меньше, чем нужно, она перестанет быть вложенной в outer — и наоборот. Отступ буквально определяет, какая функция находится «внутри» какой.

nonlocal

Как и с глобальными переменными, ПРОЧИТАТЬ имя из объемлющей функции можно свободно, а вот ИЗМЕНИТЬ (присвоить) — нужно явно попросить:

nonlocal.py
def outer():
    count = 0

    def inner():
        nonlocal count
        count += 1

    inner()
    inner()
    print(count)

outer()
2
nonlocal позволил inner() изменить count из outer(), а не создать свою локальную копию
nonlocal — это НЕ global
nonlocal ищет имя в БЛИЖАЙШЕЙ подходящей объемлющей функции — не на уровне модуля. Если убрать nonlocal count, получится та же ошибка UnboundLocalError, что и в §13.12 — по той же самой причине: присваивание внутри inner сделало бы count локальным именем самой inner.

Чуть глубже — замыкание (closure)

Вложенная функция способна «запомнить» значения из объемлющей функции даже после того, как внешний вызов уже завершился:

closure.py
def make_greeter(name):
    def greet():
        print(f"Привет, {name}!")
    return greet

greet_anna = make_greeter("Anna")
greet_anna()   # Привет, Anna! — хотя make_greeter уже закончила работу
Замыкание — тема на будущее
Это называется замыканиемgreet «уносит с собой» доступ к name. Здесь достаточно увидеть, что так вообще бывает — подробный разбор замыканий и их практических применений (декораторы и не только) не входит в эту главу.
Практика: вложенные функции и nonlocal
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →