python - referenced - Variable global con importaciones
python class (3)
first.py
myGlobal = "hello"
def changeGlobal():
myGlobal="bye"
segundo.py
from first import *
changeGlobal()
print myGlobal
La salida que obtengo es
Hola
aunque pensé que debería ser
adiós
¿Por qué no cambia la variable global myGlobal
después de la llamada a la función changeGlobal()
?
Tratar:
def changeGlobal():
global myGlobal
myGlobal = "bye"
En realidad, eso tampoco funciona. Cuando import *
, crea un nuevo módulo local global myGlobal
que es inmune al cambio que pretende (siempre y cuando no esté mutando la variable, vea más abajo). Puedes usar esto en su lugar:
import nice
nice.changeGlobal()
print nice.myGlobal
O:
myGlobal = "hello"
def changeGlobal():
global myGlobal
myGlobal="bye"
changeGlobal()
Sin embargo, si su global es un contenedor mutable, ahora tiene una referencia a un mutable y puede ver los cambios realizados en él:
myGlobal = ["hello"]
def changeGlobal():
myGlobal[0] = "bye"
Una vez tuve la misma preocupación que la tuya, y leer la siguiente sección del Rápido y sin dolor de Python Tutorial de Norman Matloff fue realmente una buena ayuda. Esto es lo que necesita entender (copiado del libro de Matloff):
Python no permite realmente las variables globales en el sentido en que lo hacen C / C ++. Un módulo Python importado no tendrá acceso directo a los globales en el módulo que lo importa, ni viceversa.
Por ejemplo, considere estos dos archivos, x.py ,
# x.py
import y
def f():
global x
x = 6
def main():
global x
x = 3
f()
y.g()
if __name__ == ’__main__’:
main()
y y.py :
# y.py
def g():
global x
x += 1
La variable x en x.py es visible en todo el módulo x.py , pero no en y.py. De hecho, la ejecución de la línea x + = 1.
en este último, aparecerá un mensaje de error, "el nombre global ''x'' no está definido".
De hecho, una variable global en un módulo es simplemente un atributo (es decir, una entidad miembro) de ese módulo, similar al rol de una variable de clase dentro de una clase. Cuando el módulo B es importado por el módulo A , el espacio de nombres de B se copia en los de A. Si el módulo B tiene una variable global X, entonces el módulo A creará una variable de ese nombre, cuyo valor inicial es el módulo B que tenía para su variable de ese nombre en el momento de la importación. Pero los cambios a X en uno de los módulos NO se reflejarán en el otro.
Digamos que X cambia en B , pero queremos que el código en A pueda obtener el último valor de X en B. Podemos hacerlo incluyendo una función, por ejemplo llamada GetX () en B. Asumiendo que A importó todo de B , entonces A obtendrá una función GetX () que es una copia de la función de B de ese nombre, y cuyo único propósito es devolver el valor de X. A menos que B cambie esa función (que es posible, por ejemplo, se pueden asignar funciones), las funciones en los dos módulos siempre serán las mismas, y así A puede usar su función para obtener el valor de X en B.
Las variables globales de Python no son globales
Como señala wassimans arriba, son esencialmente atributos dentro del alcance del módulo en el que están definidos (o el módulo que contiene la función que los definió).
La primera confusión (error) con la que se encuentra la gente es no darse cuenta de que las funciones tienen un espacio de nombres local y que establecer una variable en una función la convierte en una función local de la función, incluso cuando pretenden que cambie una variable (global) de la misma Nombre en el módulo adjunto. (declarar el nombre en una declaración ''global'' en la función, o acceder a la variable (global) antes de establecerla).
La segunda confusión (error) con la que se encuentra la gente es que cada módulo (es decir, un archivo importado) contiene su propio espacio de nombres denominado ''global''. Supongo que Python Things the World (globo) es el módulo, tal vez estamos buscando variables ''universales'' que abarquen más de un globo.
La tercera confusión (que estoy empezando a entender ahora) es ¿dónde están los ''globales'' en el módulo __main__
? Es decir, si inicia python desde la línea de comandos en modo interactivo, o si invoca el script de python (escriba el nombre de foo.py desde el comando shell), no hay importación de un módulo cuyo nombre pueda usar.
El contenido de ''globals ()'' o globals (). Keys (), que le da una lista de las opciones globales, parece ser accesible como: dir (sys.modules ['' __main__
'']) Parece que el módulo para la secuencia de comandos de Python cargada (o la sesión interactiva sin secuencia de comandos cargada), la que lleva el nombre: __name__
, no tiene nombre global, pero es accesible como el módulo cuyo nombre es '' __main__
'' en la lista del sistema de todos los módulos activos, sys .módulos