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.

¿Fue útil?

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 valor x 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 una   global 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ón nonlocal.

     

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top