¿Por qué no se necesita la palabra clave "global" para acceder a una variable global?
Según tengo entendido, Python tiene un espacio de nombres separado para funciones, por lo que si quiero usar una variable global en una función, probablemente debería usar global
.
Sin embargo, pude acceder a una variable global incluso sin global
:
>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
... return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'
¿Por qué funciona esto?
Consulte también UnboundLocalError en la variable local cuando se reasigna después del primer uso para conocer el error que se produce al intentar asignar a la variable global sin global
. Consulte Uso de variables globales en una función para conocer la pregunta general sobre cómo usar variables globales.
La palabra clave global
sólo es útil para cambiar o crear variables globales en un contexto local, aunque la creación de variables globales rara vez se considera una buena solución.
def bob():
me = "locally defined" # Defined only in local context
print(me)
bob()
print(me) # Asking for a global variable
Lo anterior le dará:
locally defined
Traceback (most recent call last):
File "file.py", line 9, in <module>
print(me)
NameError: name 'me' is not defined
Mientras que si usa la global
declaración, la variable estará disponible "fuera" del alcance de la función, convirtiéndose efectivamente en una variable global.
def bob():
global me
me = "locally defined" # Defined locally but declared as global
print(me)
bob()
print(me) # Asking for a global variable
Entonces el código anterior te dará:
locally defined
locally defined
Además, debido a la naturaleza de Python, también puedes usarlo global
para declarar funciones, clases u otros objetos en un contexto local. Aunque lo desaconsejaría ya que causa pesadillas si algo sale mal o necesita depurarse.
Si bien puede acceder a variables globales sin la global
palabra clave, si desea modificarlas debe usar la global
palabra clave. Por ejemplo:
foo = 1
def test():
foo = 2 # new local foo
def blub():
global foo
foo = 3 # changes the value of the global foo
En tu caso, recién estás accediendo a la lista sub
.
Ésta es la diferencia entre acceder al nombre y vincularlo dentro de un alcance.
Si solo está buscando una variable para leer su valor, tiene acceso al alcance global y local.
Sin embargo, si asigna a una variable cuyo nombre no está en el ámbito local, está vinculando ese nombre a este ámbito (y si ese nombre también existe como global, lo ocultará).
Si desea poder asignar el nombre global, debe indicarle al analizador que use el nombre global en lugar de vincular un nuevo nombre local, que es lo que hace la palabra clave 'global'.
La vinculación en cualquier lugar dentro de un bloque hace que el nombre en todas partes de ese bloque quede vinculado, lo que puede causar algunas consecuencias bastante extrañas (por ejemplo, UnboundLocalError aparece repentinamente en un código que funcionaba anteriormente).
>>> a = 1
>>> def p():
print(a) # accessing global scope, no binding going on
>>> def q():
a = 3 # binding a name in local scope - hiding global
print(a)
>>> def r():
print(a) # fail - a is bound to local scope, but not assigned yet
a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
r()
File "<pyshell#32>", line 2, in r
print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>>
Las otras respuestas responden a tu pregunta. Otra cosa importante que debe saber sobre los nombres en Python es que son locales o globales según el ámbito.
Considere esto, por ejemplo:
value = 42
def doit():
print value
value = 0
doit()
print value
Probablemente puedas adivinar que la value = 0
declaración se asignará a una variable local y no afectará el valor de la misma variable declarada fuera de la doit()
función. Es posible que se sorprenda aún más al descubrir que el código anterior no se ejecutará. La declaración print value
dentro de la función produce unaUnboundLocalError.
La razón es que Python ha notado que, en otra parte de la función, le asignas el nombre value
, y además value
no está declarado en ninguna parte global
. Eso la convierte en una variable local. Pero cuando intenta imprimirlo, el nombre local aún no se ha definido. Python en este caso no recurre a buscar el nombre como una variable global, como lo hacen otros lenguajes. Básicamente, no puede acceder a una variable global si ha definido una variable local con el mismo nombre en cualquier parte de la función.