Pregunta Usar variables globales en una función


¿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? ¿Debo almacenar la variable global en una variable local de la función que necesita su acceso?


2466
2018-01-08 05:45


origen


Respuestas:


Puede usar una variable global en otras funciones declarándola como global en cada función que le asigna:

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

Me imagino que la razón es que, dado que las variables globales son tan peligrosas, Python quiere asegurarse de que realmente sepas que es con lo que estás jugando al requerir explícitamente el global palabra clave.

Vea otras respuestas si desea compartir una variable global entre los módulos.


3497
2018-01-08 08:39



Si entiendo tu situación correctamente, lo que estás viendo es el resultado de cómo maneja Python los espacios de nombres locales (funciones) y globales (módulos).

Digamos que tienes un módulo como este:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Puede esperar que imprima 42, pero imprime 5. Como ya se ha mencionado, si agrega un 'global'declaración a func1(), entonces func2() se imprimirá 42.

def func1():
    global myGlobal
    myGlobal = 42

Lo que sucede aquí es que Python supone que cualquier nombre que sea asignado a, en cualquier lugar dentro de una función, es local para esa función a menos que se indique explícitamente lo contrario. Si solo es leyendo desde un nombre, y el nombre no existe localmente, intentará buscar el nombre en cualquier ámbito que lo 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 sale del alcance y es basura recogida cuando func1() devoluciones; mientras tanto, func2() nunca puede ver nada más que el nombre global (no modificado). Tenga en cuenta que esta decisión de espacio de nombres ocurre en tiempo de compilación, no en tiempo de ejecución, si debe leer el valor de myGlobal dentro func1() antes de asignarlo, obtendrías un UnboundLocalError, porque Python ya ha decidido que debe ser una variable local pero aún no tiene ningún valor asociado. Pero al usar el 'global'declaración, le dice a Python que debería buscar el nombre en otro lugar en lugar de asignarlo localmente.

(Creo que este comportamiento se originó principalmente 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.


660
2018-01-08 09:19



Es posible que desee explorar la noción de espacios de nombres. En Python, el módulo es el lugar natural para global datos:

Cada módulo tiene su propia tabla de símbolos privada, que se utiliza como la tabla de símbolos global por todas las funciones definidas en el módulo. Por lo tanto, el autor de un módulo puede usar variables globales en el módulo sin preocuparse por los choques accidentales con las variables globales de un usuario. Por otro lado, si sabe lo que está haciendo, puede tocar las variables globales de un módulo con la misma notación utilizada para referirse a sus funciones, modname.itemname.

Aquí se describe un uso específico de global-in-a-module: how-do-i-share-global-variables-across-modulesy, para completar, los contenidos se comparten aquí:

La forma canónica de compartir información entre módulos dentro de un solo programa es crear un módulo de configuración especial (a menudo llamado config o cfg). Solo importa el módulo de configuración en todos los módulos de tu aplicación; el módulo queda disponible como un nombre global. Como solo hay una instancia de cada módulo, cualquier cambio realizado en el objeto del módulo se refleja en todas partes. Por ejemplo:

Archivo: config.py

x = 0   # Default value of the 'x' configuration setting

Archivo: mod.py

import config
config.x = 1

Archivo: main.py

import config
import mod
print config.x

175
2018-01-08 05:59



Python usa una heurística simple para decidir de qué alcance debe cargar una variable, entre local y global. Si aparece un nombre de variable en el lado izquierdo de una tarea, pero no se declara global, se asume que es local. Si no aparece en el lado izquierdo de una tarea, se supone que es global.

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

Vea cómo baz, que aparece en el lado izquierdo de una tarea en foo(), es el único LOAD_FAST variable.


75
2017-07-12 12:35



Si desea hacer referencia a una variable global en una función, puede usar global palabra clave para declarar qué variables son globales. No tiene que usarlo en todos los casos (como alguien afirma incorrectamente): si el nombre al que se hace referencia en una expresión no se puede encontrar en ámbito local o ámbitos en las funciones en las que se define esta función, se busca entre los sistemas globales variables.

Sin embargo, si asigna 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 los scripts más pequeños, donde el OOP es excesivo.


47
2018-01-08 09:03



Además de las respuestas ya existentes y para hacer esto más confuso:

En Python, las variables a las que solo se hace referencia dentro de una función son    implícitamente global. Si a una variable se le asigna un nuevo valor en cualquier lugar   dentro del cuerpo de la función, se supone que es un local. Si una variable   se le ha asignado un nuevo valor dentro de la función, la variable es   implícitamente local, y necesita declararlo explícitamente como 'global'.

Aunque un poco sorprendente al principio, la explicación de un momento explica   esta. Por un lado, requerir global para las variables asignadas proporciona una   barra contra los efectos secundarios no deseados. Por otro lado, si global era   requerido para todas las referencias globales, estarías usando global   hora. Tendría que declarar como global cada referencia a un built-in   función o a un componente de un módulo importado. Este desorden   vencer la utilidad de la declaración global para identificar   efectos secundarios.

Fuente: ¿Cuáles son las reglas para las variables locales y globales en Python?.


36
2017-07-04 10:23



Si creo una variable global en una función, ¿cómo puedo usar esa variable en otra función?

Podemos crear un global con la siguiente función:

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 

Escribir una función en realidad no ejecuta su código. Entonces llamamos al create_global_variable función:

>>> create_global_variable()

Usar globales sin modificación

Puede usarlo, siempre que no espere cambiar a qué objeto apunta:

Por ejemplo,

def use_global_variable():
    return global_variable + '!!!'

y ahora podemos usar la variable global:

>>> use_global_variable()
'Foo!!!'

Modificación de la variable global desde dentro de una función

Para señalar la variable global en un objeto diferente, debe usar la palabra clave global nuevamente:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

Tenga en cuenta que después de escribir esta función, el código que realmente lo está cambiando todavía no se ha ejecutado:

>>> use_global_variable()
'Foo!!!'

Entonces, después de llamar a la función:

>>> change_global_variable()

podemos ver que la variable global ha sido modificada. los global_variable nombre ahora apunta a 'Bar':

>>> use_global_variable()
'Bar!!!'

Tenga en cuenta que "global" en Python no es realmente global, solo es global a nivel de módulo. Por lo tanto, solo está disponible para las funciones escritas en los módulos en los que es global. Las funciones recuerdan el módulo en el que están escritas, de modo que cuando se exportan a otros módulos, todavía buscan en el módulo en el que se crearon para encontrar variables globales.

Variables locales con el mismo nombre

Si crea una variable local con el mismo nombre, eclipsará una variable global:

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

Pero usar esa variable local mal llamada no cambia la variable global:

>>> use_global_variable()
'Bar!!!'

Tenga en cuenta que debe evitar usar las variables locales con los mismos nombres que las globales a menos que sepa exactamente lo que está haciendo y tenga una muy buena razón para hacerlo. Todavía no he encontrado una razón tal.


31
2018-01-01 19:55



Con la ejecución en paralelo, las variables globales pueden causar resultados inesperados si no entiendes lo que está sucediendo. Aquí hay un ejemplo del uso de una variable global dentro de multiprocesamiento. Podemos ver claramente que cada proceso funciona con su propia copia de la variable:

import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

Salida:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]

28
2017-10-03 05:41



Debe hacer referencia a la variable global en cada función que desee utilizar.

Como sigue:

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""

19
2017-12-20 12:45



Lo que estás diciendo es usar el método así:

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

Pero la mejor manera es usar la variable global de esta manera:

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

Ambos dan el mismo resultado.


19
2017-12-04 06:27