Python 3: UnboundLocalError: variable local a la que se hace referencia antes de la asignación

El siguiente código da el error UnboundLocalError: local variable 'Var1' referenced before assignment :

 Var1 = 1 Var2 = 0 def function(): if Var2 == 0 and Var1 > 0: print("Result One") elif Var2 == 1 and Var1 > 0: print("Result Two") elif Var1 < 1: print("Result Three") Var1 =- 1 function() 

¿Cómo puedo arreglar esto? ¡Gracias por cualquier ayuda!

Puedes arreglar esto pasando parámetros en lugar de confiar en Globals

 def function(Var1, Var2): if Var2 == 0 and Var1 > 0: print("Result One") elif Var2 == 1 and Var1 > 0: print("Result Two") elif Var1 < 1: print("Result Three") return Var1 - 1 function(1, 1) 

Esto se debe a que, aunque Var1 existe, también está utilizando una statement de asignación en el nombre Var1 dentro de la función ( Var1 -= 1 en la línea inferior). Naturalmente, esto crea una variable dentro del scope de la función llamada Var1 (sinceramente, un -= o += solo actualizará (reasignará) una variable existente, pero por razones desconocidas (posible coherencia en este contexto), Python la trata como una asignación) . El intérprete de Python ve esto en el tiempo de carga del módulo y decide (correctamente) que el Var1 del scope global no debe usarse dentro del scope local, lo que ocasiona un problema cuando intenta hacer referencia a la variable antes de asignarla localmente.

El uso de variables globales, fuera de la necesidad, suele ser mal visto por los desarrolladores de Python, porque conduce a un código confuso y problemático. Sin embargo, si desea usarlos para cumplir lo que su código implica, simplemente puede agregar:

 global Var1, Var2 

dentro de la parte superior de su función. Esto le dirá a Python que no tiene la intención de definir una variable Var1 o Var2 dentro del scope local de la función. El intérprete de Python ve esto en el tiempo de carga del módulo y decide (correctamente) buscar cualquier referencia a las variables antes mencionadas en el ámbito global.

Algunos recursos

  • El sitio web de Python tiene una gran explicación para este problema común.
  • Python 3 ofrece una statement nonlocal relacionada: compruébalo también.

Si establece el valor de una variable dentro de la función, Python lo entiende como la creación de una variable local con ese nombre. Esta variable local enmascara la variable global.

En su caso, Var1 se considera como una variable local, y se usa antes de configurarse, por lo tanto, el error.

Para resolver este problema, puede decir explícitamente que es global al poner global Var1 en su función.

 Var1 = 1 Var2 = 0 def function(): global Var1 if Var2 == 0 and Var1 > 0: print("Result One") elif Var2 == 1 and Var1 > 0: print("Result Two") elif Var1 < 1: print("Result Three") Var1 =- 1 function() 

No me gusta este comportamiento, pero así es como funciona Python. La pregunta ya ha sido respondida por otros, pero para completar, permítanme señalar que Python 2 tiene más de esas peculiaridades.

 def f(x): return x def main(): print f(3) if (True): print [f for f in [1, 2, 3]] main() 

Python 2.7.6 devuelve un error:

 Traceback (most recent call last): File "weird.py", line 9, in  main() File "weird.py", line 5, in main print f(3) UnboundLocalError: local variable 'f' referenced before assignment 

Python ve que f se usa como una variable local en [f for f in [1, 2, 3]] , y decide que también es una variable local en f(3) . Usted podría agregar una statement global f :

 def f(x): return x def main(): global f print f(3) if (True): print [f for f in [1, 2, 3]] main() 

Funciona; sin embargo, f se convierte en 3 al final … Es decir, print [f for f in [1, 2, 3]] ahora cambia la variable global f a 3 , por lo que ya no es una función.

Afortunadamente, funciona bien en Python3 después de agregar los paréntesis para print .

¿Por qué no simplemente devolver el valor calculado y dejar que la persona que llama modifique la variable global? No es una buena idea manipular una variable global dentro de una función, como se muestra a continuación:

 Var1 = 1 Var2 = 0 def function(): if Var2 == 0 and Var1 > 0: print("Result One") elif Var2 == 1 and Var1 > 0: print("Result Two") elif Var1 < 1: print("Result Three") return Var1 - 1 Var1 = function() 

o incluso haga copias locales de las variables globales y trabaje con ellas y devuelva los resultados que la persona que llama puede asignar adecuadamente

 def function(): v1, v2 = Var1, Var2 # calculate using the local variables v1 & v2 return v1 - 1 Var1 = function()