Что делает оператор Python nonlocal
(в Python 3.0 и выше)?
Там нет документации на официальном веб-сайте Python и help("nonlocal")
тоже.
Что делает оператор Python nonlocal
(в Python 3.0 и выше)?
Там нет документации на официальном веб-сайте Python и help("nonlocal")
тоже.
Сравните это, не используя 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
Короче говоря, он позволяет присваивать значения переменной во внешней (но неглобальной) области. См. PEP 3104 для всех деталей gory.
помощь ( 'нелокальный') Оператор
nonlocal
nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*
Оператор
nonlocal
заставляет перечисленные идентификаторы ссылаться на ранее связанные переменные в ближайшей охватывающей области. Это важно, потому что поведение по умолчанию для привязки - поиск локальное пространство имен. Этот оператор позволяет инкапсулированному коду перегруппировки переменных за пределами локальной области, помимо глобальных (модуль).Имена, перечисленные в инструкции
nonlocal
, в отличие от тех, которые перечислены вglobal
, должен ссылаться на ранее существующие привязки в (область, в которой необходимо создать новое связывание) не может быть однозначно определена).Имена, перечисленные в операторе
nonlocal
, не должны сталкиваться с пред- существующие привязки в локальной области.См. также:
PEP 3104 - доступ к именам во внешних областях
Спецификация для оператораnonlocal
.Связанные разделы справки: global, NAMESPACES
Источник: Справочник по языку Python
@ooboo:
Он берет один "самый близкий" к точке отсчета в исходном коде. Это называется "Lexical Scoping" и стандартно для > 40 лет.
Члены класса Python действительно находятся в словаре под названием __dict__
и никогда не будут достигнуты лексическим охватом.
Если вы не укажете nonlocal
, но выполните x = 7
, он создаст новую локальную переменную "x" .
Если вы укажете nonlocal
, он найдет "ближайший" "x" и назначит этому.
Если вы укажете nonlocal
и нет "x" , оно выдаст вам сообщение об ошибке.
Ключевое слово global
всегда казалось мне странным, так как он с радостью проигнорирует все остальные "х", кроме самого внешнего. Weird.
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)
Мое личное понимание "нелокального" утверждения (и извините меня за то, что я новичок в Python и программирование в целом) заключается в том, что "нелокальный" способ использовать глобальную функциональность внутри итерированных функций, а не для тела сам код. Глобальное выражение между функциями, если вы это сделаете.
с "нелокальными" внутренними функциями (т.е. вложенными внутренними функциями) может быть прочитано и " написать" для этой конкретной переменной внешней родительской функции. И нелокальные могут использоваться только внутри внутренних функций например:
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)
Цитата из 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