2012-08-16 26 views
41

En el segundo caso a continuación, Python intenta buscar una variable local. Cuando no encuentra uno, ¿por qué no puede verse en el ámbito externo como lo hace para el primer caso?Por qué las funciones anidadas pueden acceder a variables desde funciones externas, pero no pueden modificarlas

Esto se ve por x en el ámbito local, el alcance continuación externa:

def f1(): 
    x = 5 
    def f2(): 
     print x 

Esto da local variable 'x' referenced before assignment error:

def f1(): 
    x = 5 
    def f2(): 
     x+=1 

no estoy autorizado a modificar la firma de la función f2() por lo No puedo pasar y devolver valores de x. Sin embargo, sí necesito una forma de modificar x. ¿Hay alguna forma de decirle explícitamente a Python que busque un nombre de variable en el ámbito externo (algo similar a la palabra clave global)?

versión Python: 2,7

+1

python 3 proporciona 'nonlocal' para este propósito, pero creo que vale la pena preguntar por qué necesita hacer esto. Esto es un poco más seguro que usar 'global', pero todavía no se siente bien. – mgilson

+2

@mgilson hay muchas buenas razones para hacerlo, ver p. la sección de razonamiento en pep-3104. – thebjorn

+0

¿Qué versión de python usas? – soulcheck

Respuesta

41
def f1(): 
    x = { 'value': 5 } 
    def f2(): 
     x['value'] += 1 

Solución alternativa es utilizar un objeto mutable y actualizar los miembros de ese objeto. El enlace de nombres es complicado en Python, a veces.

+0

Esto funciona, aunque terminé usando una lista con un solo elemento en lugar de un diccionario. ¡Gracias! – Dhara

+5

Creo que es más correcto usar 'nonlocal' o' global' – bgusach

+2

Global no es una buena idea ya que contaminará el espacio de nombres global. Nonlocal es una característica de python 3, y esta pregunta especificó python 2.7. –

38

En Python 3.x esto es posible:

def f1(): 
     x = 5 
     def f2(): 
       nonlocal x 
       x+=1 
     return f2 

El problema y una solución a ella, para Python 2.x, así, se dan en la this poste. Además, lea PEP 3104 para obtener más información sobre este tema.

+0

Acabo de ver esto. 'nonlocal' es la declaración para usar aquí. – mgilson

+0

uso global en lugar de no local para Python 2.x – User

+3

@ user1320237 global no funciona en lugar de no local - ¡esa fue precisamente mi pregunta! – Dhara

Cuestiones relacionadas