Нелокальное утверждение Python

Что делает оператор Python nonlocal (в Python 3.0 и выше)?

Там нет документации на официальном веб-сайте Python и help("nonlocal") тоже.

Ответ 1

Сравните это, не используя nonlocal:

x = 0
def outer():
    x = 1
    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 0

Для этого, используя nonlocal, где inner() x теперь также outer() x:

x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 2
# global: 0

Если бы мы использовали global, он привязал бы x к правильному "глобальному" значению:

x = 0
def outer():
    x = 1
    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 2

Ответ 2

Короче говоря, он позволяет присваивать значения переменной во внешней (но неглобальной) области. См. PEP 3104 для всех деталей gory.

Ответ 3

Поиск Google для "python nonlocal" поднял предложение

Ответ 4

помощь ( 'нелокальный') Оператор nonlocal


    nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*

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

Имена, перечисленные в инструкции nonlocal, в отличие от тех, которые перечислены в global, должен ссылаться на ранее существующие привязки в (область, в которой необходимо создать новое связывание) не может быть однозначно определена).

Имена, перечисленные в операторе nonlocal, не должны сталкиваться с пред- существующие привязки в локальной области.

См. также:

PEP 3104 - доступ к именам во внешних областях
      Спецификация для оператора nonlocal.

Связанные разделы справки: global, NAMESPACES

Источник: Справочник по языку Python

Ответ 5

@ooboo:

Он берет один "самый близкий" к точке отсчета в исходном коде. Это называется "Lexical Scoping" и стандартно для > 40 лет.

Члены класса Python действительно находятся в словаре под названием __dict__ и никогда не будут достигнуты лексическим охватом.

Если вы не укажете nonlocal, но выполните x = 7, он создаст новую локальную переменную "x" . Если вы укажете nonlocal, он найдет "ближайший" "x" и назначит этому. Если вы укажете nonlocal и нет "x" , оно выдаст вам сообщение об ошибке.

Ключевое слово global всегда казалось мне странным, так как он с радостью проигнорирует все остальные "х", кроме самого внешнего. Weird.

Ответ 6

a = 0    #1. global variable with respect to every function in program

def f():
    a = 0          #2. nonlocal with respect to function g
    def g():
        nonlocal a
        a=a+1
        print("The value of 'a' using nonlocal is ", a)
    def h():
        global a               #3. using global variable
        a=a+5
        print("The value of a using global is ", a)
    def i():
        a = 0              #4. variable separated from all others
        print("The value of 'a' inside a function is ", a)

    g()
    h()
    i()
print("The value of 'a' global before any function", a)
f()
print("The value of 'a' global after using function f ", a)

Ответ 7

Мое личное понимание "нелокального" утверждения (и извините меня за то, что я новичок в Python и программирование в целом) заключается в том, что "нелокальный" способ использовать глобальную функциональность внутри итерированных функций, а не для тела сам код. Глобальное выражение между функциями, если вы это сделаете.

Ответ 8

с "нелокальными" внутренними функциями (т.е. вложенными внутренними функциями) может быть прочитано и " написать" для этой конкретной переменной внешней родительской функции. И нелокальные могут использоваться только внутри внутренних функций например:

a = 10
def Outer(msg):
    a = 20
    b = 30
    def Inner():
        c = 50
        d = 60
        print("MU LCL =",locals())
        nonlocal a
        a = 100
        ans = a+c
        print("Hello from Inner",ans)       
        print("value of a Inner : ",a)
    Inner()
    print("value of a Outer : ",a)

res = Outer("Hello World")
print(res)
print("value of a Global : ",a)

Ответ 9

Цитата из Python 3 Reference:

Нелокальный оператор заставляет перечисленные идентификаторы ссылаться на ранее связанные переменные в ближайшей охватывающей области, исключая глобальные переменные.

Как сказано в ссылке, в случае нескольких вложенных функций изменяется только переменная в ближайшей закрывающей функции:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        x = 2
        innermost()
        if x == 3: print('Inner x has been modified')

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Inner x has been modified

"ближайшая" переменная может находиться на нескольких уровнях:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Outer x has been modified

Но это не может быть глобальная переменная:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    inner()

x = 0
outer()
if x == 3: print('Global x has been modified')

# SyntaxError: no binding for nonlocal 'x' found