¿Cómo puedo crear o usar una variable global en una función?
Si creo una variable global en una función, ¿cómo puedo usar esa variable global en otra función? ¿Necesito almacenar la variable global en una variable local de la función que necesita su acceso?
python
global-variables
scope
usuario46646
fuente
fuente
global
palabra clave sea porque los globales son peligrosos. Más bien, se debe a que el lenguaje no requiere que declare explícitamente las variables y automáticamente asume que una variable que asigna tiene un alcance de función a menos que le indique lo contrario. Laglobal
palabra clave es el medio que se proporciona para indicarle lo contrario.f2()
cambian de estado por lo que ahoraf3()
podría hacer algo inesperado Las funciones pueden ahora operar agnóstico a otro programa externo?.Si entiendo su situación correctamente, lo que está viendo es el resultado de cómo Python maneja los espacios de nombres locales (funciones) y globales (módulos).
Digamos que tienes un módulo como este:
Es posible que espere que esto imprima 42, pero en su lugar imprime 5. Como ya se mencionó, si agrega una
global
declaración ' 'func1()
,func2()
imprimirá 42.Lo que está sucediendo aquí es que Python asume que cualquier nombre asignado a , en cualquier lugar dentro de una función, es local a esa función a menos que se indique explícitamente lo contrario. Si solo lee un nombre y el nombre no existe localmente, intentará buscar el nombre en cualquier ámbito que contenga (por ejemplo, el alcance global del módulo).
Cuando asigna 42 al nombre
myGlobal
, por lo tanto, Python crea una variable local que sombrea la variable global del mismo nombre. Ese local queda fuera de alcance y se recolecta basura cuandofunc1()
regresa; Mientras tanto,func2()
nunca puede ver otra cosa que no sea el nombre global (sin modificar). Tenga en cuenta que esta decisión de espacio de nombres ocurre en el momento de la compilación, no en tiempo de ejecución: si tuviera que leer el valor demyGlobal
insidefunc1()
antes de asignarlo, obtendría unUnboundLocalError
, porque Python ya ha decidido que debe ser una variable local pero aún no ha tenido ningún valor asociado. Pero al usar laglobal
instrucción ' ', le dice a Python que debe buscar el nombre en otro lugar en lugar de asignarlo localmente.(Creo que este comportamiento se originó en gran medida a través de una optimización de los espacios de nombres locales; sin este comportamiento, la VM de Python necesitaría realizar al menos tres búsquedas de nombres cada vez que se asigna un nuevo nombre dentro de una función (para asegurarse de que el nombre no t ya existe en el módulo / nivel integrado), lo que ralentizaría significativamente una operación muy común).
fuente
MyGlobal = 5
x
es local es diferente de verificar en tiempo de ejecución si el nombre local estaba vinculado a un valor antes de que se use la primera vez.MY_GLOBAL = 5
. Consulte la Guía de estilo para el código Python .Es posible que desee explorar la noción de espacios de nombres . En Python, el módulo es el lugar natural para los datos globales :
Aquí se describe un uso específico de global-in-a-module: ¿cómo comparto variables globales entre módulos? , y para completar, los contenidos se comparten aquí:
fuente
config.x
¿puedo deshacerme de él? Vine conx = lambda: config.x
y luego tengo el nuevo valorx()
. por alguna razón, tenera = config.x
no me sirve de nada.from config import x
resuelve eso?Python utiliza una heurística simple para decidir desde qué ámbito debe cargar una variable, entre local y global. Si aparece un nombre de variable en el lado izquierdo de una asignación, pero no se declara global, se supone que es local. Si no aparece en el lado izquierdo de una tarea, se supone que es global.
Vea cómo baz, que aparece en el lado izquierdo de una tarea en
foo()
, es la únicaLOAD_FAST
variable.fuente
for
bucle y el nombre después deas
enwith
y lasexcept
declaraciones también están vinculados.as
en unaexcept
cláusula, esto no era obvio para mí. Pero se elimina automáticamente para ahorrar memoria.as ...
destino en el controlador de excepciones.Si desea hacer referencia a una variable global en una función, puede usar la palabra clave global para declarar qué variables son globales. No tiene que usarlo en todos los casos (como alguien aquí afirma incorrectamente): si el nombre al que se hace referencia en una expresión no se puede encontrar en el ámbito local o en los ámbitos en las funciones en las que se define esta función, se busca entre variables
Sin embargo, si asigna a una nueva variable no declarada como global en la función, se declara implícitamente como local y puede eclipsar cualquier variable global existente con el mismo nombre.
Además, las variables globales son útiles, al contrario de algunos fanáticos de OOP que afirman lo contrario, especialmente para scripts más pequeños, donde OOP es excesivo.
fuente
Podemos crear un global con la siguiente función:
Escribir una función en realidad no ejecuta su código. Entonces llamamos a la
create_global_variable
función:Usando globals sin modificación
Simplemente puede usarlo, siempre y cuando no espere cambiar a qué objeto apunta:
Por ejemplo,
y ahora podemos usar la variable global:
Modificación de la variable global desde una función.
Para apuntar la variable global a un objeto diferente, debe usar la palabra clave global nuevamente:
Tenga en cuenta que después de escribir esta función, el código que realmente la cambia aún no se ha ejecutado:
Entonces, después de llamar a la función:
Podemos ver que la variable global ha cambiado. El
global_variable
nombre ahora apunta a'Bar'
:Tenga en cuenta que "global" en Python no es verdaderamente global, solo es global al nivel del módulo. Por lo tanto, solo está disponible para funciones escritas en los módulos en los que es global. Las funciones recuerdan el módulo en el que están escritas, por lo que cuando se exportan a otros módulos, aún buscan en el módulo en el que fueron creadas para encontrar variables globales.
Variables locales con el mismo nombre.
Si crea una variable local con el mismo nombre, eclipsará una variable global:
Pero usar esa variable local mal nombrada no cambia la variable global:
Tenga en cuenta que debe evitar usar las variables locales con los mismos nombres que los globales, a menos que sepa exactamente lo que está haciendo y tenga una muy buena razón para hacerlo. Todavía no he encontrado tal razón.
Tenemos el mismo comportamiento en las clases.
Un seguimiento en el comentario pregunta:
Aquí demuestro que obtenemos el mismo comportamiento en los métodos que en las funciones regulares:
Y ahora:
Pero sugeriría que, en lugar de usar variables globales, use atributos de clase, para evitar saturar el espacio de nombres del módulo. También tenga en cuenta que no usamos
self
argumentos aquí; estos podrían ser métodos de clase (útiles si muta el atributo de clase delcls
argumento habitual ) o métodos estáticos (noself
ocls
).fuente
Además de las respuestas ya existentes y para hacer esto más confuso:
Fuente: ¿Cuáles son las reglas para las variables locales y globales en Python? .
fuente
Con la ejecución paralela, las variables globales pueden causar resultados inesperados si no comprende lo que está sucediendo. Aquí hay un ejemplo del uso de una variable global dentro del multiprocesamiento. Podemos ver claramente que cada proceso funciona con su propia copia de la variable:
Salida:
fuente
Lo que estás diciendo es usar el método de esta manera:
Pero la mejor manera es usar la variable global de esta manera:
Ambos dan la misma salida.
fuente
Como resultado, la respuesta siempre es simple.
Aquí hay un pequeño módulo de muestra con una forma simple de mostrarlo en una
main
definición:Aquí está cómo mostrarlo en una
main
definición:Este código simple funciona así, y se ejecutará. Espero que ayude.
fuente
global_vars
e inicializo los datosinit_global_vars
que se llaman en el script de inicio. Luego, simplemente creo un método de acceso para cada var global definida. ¡Espero poder votar esto varias veces! Gracias Peter!Debe hacer referencia a la variable global en cada función que desee utilizar.
Como sigue:
fuente
En realidad, no está almacenando el global en una variable local, solo está creando una referencia local al mismo objeto al que se refiere su referencia global original. Recuerde que casi todo en Python es un nombre que se refiere a un objeto, y nada se copia en la operación habitual.
Si no tuviera que especificar explícitamente cuándo un identificador debía referirse a un global predefinido, presumiblemente tendría que especificar explícitamente cuándo un identificador es una nueva variable local (por ejemplo, con algo como el comando 'var' visto en JavaScript). Dado que las variables locales son más comunes que las variables globales en cualquier sistema serio y no trivial, el sistema de Python tiene más sentido en la mayoría de los casos.
Usted podría tener un lenguaje que trataba de adivinar, utilizando una variable global si existía o crear una variable local si no lo hizo. Sin embargo, eso sería muy propenso a errores. Por ejemplo, importar otro módulo podría introducir inadvertidamente una variable global con ese nombre, cambiando el comportamiento de su programa.
fuente
Prueba esto:
fuente
En caso de que tenga una variable local con el mismo nombre, es posible que desee utilizar la
globals()
función .fuente
Siguiendo y como complemento, use un archivo para contener todas las variables globales, todas declaradas localmente y luego
import as
:Archivo initval.py :
Archivo getstocks.py :
fuente
import ... as ...
? ¿Por qué no soloimport ...
?global
:-) => +1 :-) Edite su respuesta para aclarar estos interrogatorios que otras personas también pueden tener. SaludosEscribir en elementos explícitos de una matriz global aparentemente no necesita la declaración global, aunque escribir en ella "al por mayor" sí tiene ese requisito:
fuente
Estoy agregando esto ya que no lo he visto en ninguna de las otras respuestas y podría ser útil para alguien que lucha con algo similar. La
globals()
función devuelve un diccionario de símbolos global mutable donde puede "mágicamente" hacer que los datos estén disponibles para el resto de su código. Por ejemplo:y
Simplemente le permitirá volcar / cargar variables fuera y dentro del espacio de nombres global. Súper conveniente, sin complicaciones, sin problemas. Estoy bastante seguro de que solo es Python 3.
fuente
globals()
siempre devuelve globales disponibles en el contexto local, por lo que una mutación aquí puede no reflejarse en otro módulo.Consulte el espacio de nombres de clase donde desea que se muestre el cambio.
En este ejemplo, el corredor está usando max de la configuración del archivo. Quiero que mi prueba cambie el valor de max cuando el corredor la esté usando.
main / config.py
main / runner.py
tests / runner_test.py
fuente
Los globales están bien, excepto con multiprocesamiento
Los problemas globales relacionados con el multiprocesamiento en diferentes plataformas / entornos como Windows / Mac OS por un lado y Linux por el otro son problemáticos.
Te mostraré esto con un ejemplo simple que señala un problema que encontré hace algún tiempo.
Si quieres entender por qué las cosas son diferentes en Windows / MacOs y Linux, debes saber eso, el mecanismo predeterminado para comenzar un nuevo proceso en ...
Son diferentes en la asignación de memoria y la inicialización ... (pero no voy a esto aquí).
Echemos un vistazo al problema / ejemplo ...
Ventanas
Si ejecuta esto en Windows (y supongo que también en MacOS), obtendrá el siguiente resultado ...
Linux
Si ejecuta esto en Linux, obtendrá lo siguiente en su lugar.
fuente