2010-07-13 10 views
5

Tengo una variable global que llamé Y_VAL que se inicializa a un valor de 2.¿Por qué Python piensa que es una variable local?

Luego tengo una función, llamada f() (por brevedad), que usa Y_VAL.

def f(): 
    y = Y_VAL 
    Y_VAL += 2 

Sin embargo, al intentar ejecutar el código, pitón da el mensaje de error:

UnboundLocalError: local variable 'Y_VAL' referenced before assignment 

Si quito la última línea Y_VAL += 2 funciona bien.

¿Por qué python piensa que Y_VAL es una variable local?

+0

posible duplicado de [¿Por qué no puedo establecer una variable global en Python?] (Http://stackoverflow.com/questions/1281184/why-cant-i-set-a-global-variable-in-python) – Mark

Respuesta

14

Falta la línea global Y_VAL dentro de la función.

Cuando Y_VAL aparece en el lado derecho de una tarea, no hay problema porque se busca primero en el ámbito local y luego se busca el alcance global. Sin embargo, en el lado izquierdo, solo puede asignar a un global de esa manera cuando haya declarado explícitamente global Y_VAL.

De the docs:

Sería imposible asignar a una variable global sin global, aunque variables libres pueden referirse a variables globales no se declaró global.

+0

¿Este comportamiento se aplica de manera diferente para los dicts? Descubrí que puedo declarar un dict global y luego asignarlo dentro de una función sin usar 'global' ... ¿podría conocer el razonamiento detrás de esto? – VMDX

+0

Hmmm, parece que tengo la misma pregunta que VMDX. Dado un diccionario global 'd', he podido agregar/cambiar sin usar la palabra clave global. ¿Cómo es este el caso? lo mismo con las listas – Paul

+0

Puede cambiar los contenidos * dentro * de la lista o dict. No puede cambiar (volver a enlazar) la referencia a la lista/dict. Entonces 'd [2:] = 3' está bien, pero' d + = [3] 'no. – bobince

1

Así es como funciona Python: La asignación siempre vincula el nombre del lado izquierdo en el espacio de nombres circundante más cercano. Dentro de una función, el espacio de nombre más cercano es el espacio de nombre local de la función.

Para asignar a una variable global, tiene que declararlo global. Pero evite global por todos los medios. Las variables globales casi siempre son un mal diseño, por lo que el uso de la palabra clave global es una buena pista de que está cometiendo errores de diseño.

0

Corrí al mismo problema que usted y tantos otros como usted, antes de darse cuenta de que necesita la declaración global. Entonces decidí mover todo a la orientación de objetos y tener tranquilidad. Llámame loco, pero simplemente no confío en mí mismo con la declaración global y no es difícil enfrentar un problema de alcance local que es difícil de depurar.

Así que recomiendo recoger todas sus variables "globales", ponerlas en una clase dentro de init (self) y no solo no tendrá que preocuparse por el alcance local sino que tendrá su código mucho mejor organizado. No es una rareza que la mayoría de los programadores prefieran OOP.

Cuestiones relacionadas