Как работает `nonlocal`?

nonlocal используется для доступа и изменения переменных из внешней, но не глобальной области видимости. Позволяет изменять переменные в родительских функциях (не глобальной области видимости), внутри вложенных функций. Без nonlocal, присваивание значения переменной внутри вложенной функции создало бы новую локальную переменную с тем же именем.

Ключевое слово nonlocal в Python используется для обращения к переменной из ближайшей внешней области видимости, но не из глобальной области видимости. По сути, оно позволяет изменять переменные, определенные в замыкающей функции (enclosing function scope), из внутренней вложенной функции.

Рассмотрим пример:


def outer_function():
    message = "Hello"

    def inner_function():
        nonlocal message
        message = "World"

    inner_function()
    print(message)  # Выведет "World"

В этом примере:

  • outer_function определяет переменную message.
  • inner_function вложена в outer_function.
  • Ключевое слово nonlocal message указывает, что переменная message, к которой идет обращение внутри inner_function, является переменной из области видимости outer_function. Без nonlocal, inner_function создала бы новую локальную переменную с именем message.
  • Таким образом, когда inner_function изменяет message, она изменяет переменную, объявленную в outer_function.

Важно отметить:

  • nonlocal нельзя использовать в глобальной области видимости.
  • nonlocal ищет переменные только в родительских функциях, но не в глобальной области видимости или встроенной области видимости.
  • Если переменная не найдена в ближайшей внешней области видимости, будет выброшена ошибка SyntaxError.
  • nonlocal используется для изменения состояния в замыканиях, когда необходимо, чтобы внутренняя функция могла изменять переменные во внешней функции.

Пример с ошибкой:


message = "Global"

def outer_function():
    def inner_function():
        nonlocal message  # Ошибка: nonlocal name 'message' found but not in any enclosing scopes
        message = "World"

    inner_function()
    print(message)

outer_function()

В этом случае, nonlocal message не работает, так как message определена в глобальной области видимости, а не в родительской функции по отношению к inner_function. Чтобы обратиться к глобальной переменной, следует использовать ключевое слово global.

В заключение, nonlocal позволяет внутренней функции изменять переменные, определенные в ее родительской функции, что полезно для управления состоянием в замыканиях.

0