Si lee una variable, Python la busca en toda la cadena de alcance. Esto quiere decir que:
GLOB_VAR = "Some string"
def some_fun():
print GLOB_VAR
imprimirá Some string
Ahora, si se escribe a una variable, Python lo busca en el ámbito local, y si no puede encontrar una variable con el nombre que le dio en el nivel local, entonces crea uno.
Esto significa que en tu ejemplo, se ha creado una variable llamada SOME_VARIABLE
local a su función some_fun
, en lugar de actualizar el mundial SOME_VARIABLE
. Este es un juego clásico de pitón.
Si desea escribir en su global, debe decirle explícitamente a Python que está hablando de una variable global que ya existe. Para hacerlo, debe usar la palabra clave global
. Por lo tanto, el siguiente:
GLOB_VAR = "Some string"
def some_fun():
global GLOB_VAR
GLOB_VAR = "Some other string"
some_fun()
print GLOB_VAR
imprimirá Some other string
.
Nota: Lo veo como una forma de alentar a las personas a mantener las variables globales de solo lectura, o al menos a pensar en lo que están haciendo.
El comportamiento es el mismo (un poco más sorprendente) cuando intenta leer primero y luego escribe en un global. En el siguiente:
GLOB_VAR = False
def some_fun():
if GLOB_VAR:
GLOB_VAR = False
some_fun()
elevará:
Traceback (most recent call last):
File "t.py", line 7, in <module>
some_fun()
File "t.py", line 4, in some_fun
if GLOB_VAR:
UnboundLocalError: local variable 'GLOB_VAR' referenced before assignment
porque desde modificaremos GLOB_VAR
, se considera una variable local.
actualización: Ely Bendersky tiene una relacionada in-depth post sobre esto que es digno de una lectura para más detalles formales.