Python declaración no local
-
12-09-2019 - |
Pregunta
¿Qué hace la declaración nonlocal
Python (en Python 3.0 y posterior)?
No hay documentación en el sitio web oficial de Python y help("nonlocal")
no funciona, tampoco.
Solución
Compare esto, sin necesidad de utilizar 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
Para esto, el uso de nonlocal
, donde inner()
de x
es ahora también de 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
Si tuviéramos que utilizar
global
, que se uniría al valorx
adecuadamente "global":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
Otros consejos
En definitiva, se le permite asignar valores a una variable en un ámbito exterior (pero no global). Ver PEP 3104 para todos los detalles morbosos.
Una búsqueda en Google de "pitón no local" se presentó la propuesta, PEP 3104 , que describe plenamente la sintaxis y el razonamiento detrás de la declaración. en pocas palabras, funciona exactamente de la misma manera que la declaración global
, excepto que se utiliza para referirse a variables que son ni global ni local para la función.
He aquí un breve ejemplo de lo que puede hacer con esto. El generador de contador puede ser reescrito para usar esto para que se parece más a los idiomas de los idiomas con los cierres.
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
Obviamente, se podría escribir esto como un generador, como:
def counter_generator():
count = 0
while True:
count += 1
yield count
y si bien esto es perfectamente pitón idiomática, parece que la primera versión sería un poco más evidente para los principiantes. Adecuadamente usando generadores, llamando a la función devuelta, es un punto de confusión común. La primera versión vuelve explícitamente una función.
@ooboo:
Se necesita el "más cercano" al punto de referencia en el código fuente. Esto se conoce como "ámbito léxico" y es estándar para> 40 años.
miembros de la clase de Python son realmente en un diccionario llamado __dict__
y nunca serán alcanzadas por ámbito léxico.
Si no se especifica, pero nonlocal
hace x = 7
, se creará una nueva variable local "x".
Si especifica nonlocal
, se encuentra el "más cercano" "x" y asignar a eso.
Si especifica nonlocal
y no hay una "x", que le dará un mensaje de error.
El global
palabra clave siempre ha parecido extraño para mí, ya que estará feliz de hacer caso omiso de los demás "x" a excepción de la más externa. Raro.
ayuda ( 'no local') La declaración
nonlocal
nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*
La declaración
nonlocal
hace que los identificadores listados para referirse a previamente consolidado variables en el ámbito de inclusión más cercano. Esto es importante, ya que el comportamiento por defecto para la unión es buscar en el espacio de nombres local en primer lugar. La declaración permite que el código encapsulado a volver a enlazar las variables fuera del ámbito local, además del mundial (Módulo) ámbito de aplicación.Los nombres que figuran en un comunicado
nonlocal
, a diferencia de los enumerados en unaglobal
declaración, debe referirse a la pre-existentes fijaciones en una encerrando alcance (el alcance en el que se debe crear una nueva unión no se puede determinar de forma inequívoca).Los nombres que figuran en un comunicado
nonlocal
no debe colisionar con pre- fijaciones existentes en el ámbito local.Vea también:
PEP 3104 - El acceso a los nombres en Outer Scopes
La especificación para la declaraciónnonlocal
.temas de ayuda relacionados: globales, espacios de nombres
Fuente: Referencia del lenguaje Python
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)
Mi comprensión personal de la declaración "no local" (y lo hacen discúlpame como yo soy nuevo en Python y programación en general) es que el "no local" es una manera de utilizar la funcionalidad global dentro de las funciones iteradas más que el cuerpo de el propio código. Una declaración global entre las funciones si se quiere.
Cita de la Python 3 Referencia :
La declaración no local hace que los identificadores listados para referirse a variables previamente consolidados en la más cercana que encierra alcance excluyendo globales.
Como se ha dicho en la referencia, en el caso de varias funciones anidadas única variable en la función envolvente más cercana se modifica:
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
La variable "más cercano" puede haber varios niveles de distancia:
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
Pero no puede ser una variable global:
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
con funciones 'no locales' interior (es decir, funciones internas anidados) pueden quedar leído y ' escribir ' permiso para esa variable específica de la función madre externa . Y no local sólo se puede utilizar dentro de funciones internas por ejemplo:
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)