Python statement no local

¿Qué hace la statement no nonlocal Python (en Python 3.0 y versiones posteriores)?

No hay documentación en el sitio web oficial de Python y la help("nonlocal") tampoco funciona.

Related of "Python statement no local"

Compara esto, sin usar 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, usando nonlocal , donde inner() x inner() ahora también es x la ( x outer() de 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 usar global , enlazaríamos x con el valor “global” adecuado:

 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 

En resumen, le permite asignar valores a una variable en un ámbito externo (pero no global). Ver PEP 3104 para todos los detalles sangrientos.

Una búsqueda en Google de “python nonlocal” mostró la Propuesta, PEP 3104 , que describe completamente la syntax y el razonamiento detrás de la statement. en resumen, funciona exactamente de la misma manera que la statement global , excepto que se usa para referirse a variables que no son globales ni locales para la función.

Aquí hay un breve ejemplo de lo que puedes hacer con esto. El generador de contador se puede reescribir para usar esto de modo que se parezca más a los idiomas de los idiomas con cierres.

 def make_counter(): count = 0 def counter(): nonlocal count count += 1 return count return counter 

Obviamente, podrías escribir esto como un generador, como:

 def counter_generator(): count = 0 while True: count += 1 yield count 

Pero si bien esta es una python perfectamente idiomática, parece que la primera versión sería un poco más obvia para los principiantes. El uso correcto de los generadores, al llamar a la función devuelta, es un punto de confusión común. La primera versión devuelve explícitamente una función.

ayuda (‘no local’) La statement nonlocal


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

La statement nonlocal hace que los identificadores enumerados se refieran a variables previamente vinculadas en el ámbito de cierre más cercano. Esto es importante porque el comportamiento predeterminado para el enlace es buscar primero en el espacio de nombres local. La statement permite que el código encapsulado vuelva a vincular variables fuera del ámbito local además del scope global (módulo).

Los nombres enumerados en una statement nonlocal , a diferencia de los listados en una statement global , deben referirse a enlaces preexistentes en un ámbito adjunto (el ámbito en el que se debe crear un nuevo enlace no se puede determinar de manera inequívoca).

Los nombres que aparecen en una statement no nonlocal no deben coincidir con los enlaces preexistentes en el ámbito local.

Ver también:

PEP 3104 – Acceso a nombres en ámbitos externos
La especificación para la statement nonlocal .

Temas de ayuda relacionados: global, NOMBRES

Fuente: Referencia del lenguaje Python

@ooboo:

Toma el “más cercano” al punto de referencia en el código fuente. Esto se denomina “scope léxico” y es estándar desde hace más de 40 años.

Los miembros de la clase de Python están realmente en un diccionario llamado __dict__ y nunca serán alcanzados por el scope léxico.

Si no especifica no nonlocal pero hace x = 7 , creará una nueva variable local “x”. Si especifica nonlocal , encontrará el “más cercano” “x” y se lo asignará. Si especifica nonlocal y no hay una “x”, le dará un mensaje de error.

La palabra clave global siempre me ha parecido extraña, ya que felizmente ignorará todas las otras “x”, excepto la más externa. Extraño.

 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 statement “no local” (y disculpe porque soy nuevo en Python y en Progtwigción en general) es que “no local” es una forma de usar la funcionalidad Global dentro de las funciones iteradas en lugar del cuerpo del código en sí. . Una statement global entre funciones si lo desea.

Cita de la referencia de Python 3 :

La statement no local hace que los identificadores enumerados se refieran a variables previamente vinculadas en el ámbito envolvente más cercano, excluyendo las globales.

Como se dijo en la referencia, en el caso de varias funciones anidadas, solo se modifica la variable en la función de cierre más cercana:

 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 cercana” puede estar a 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 internas “no locales” (es decir, funciones internas anidadas) se puede obtener permiso de lectura y ” escriturapara esa variable específica de la función principal externa . Y no local puede usarse solo 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)