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

Author: Aran-Fey, 2009-01-08

18 answers

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

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 la palabra clave global.

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

 3587
Author: Paul Stephenson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-01 03:40:54

Si estoy entendiendo su situación correctamente, lo que está viendo es el resultado de cómo Python maneja los espacios de nombres locales (función) y globales (módulo).

Digamos que tienes un módulo como este:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Es posible que espere que esto imprima 42, pero en su lugar imprime 5. Como ya se ha mencionado, si agrega una declaración' global ' a func1(), entonces func2() imprimirá 42.

def func1():
    global myGlobal
    myGlobal = 42

Lo que está pasando aquí es que Python asume que cualquier nombre que se 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 está leyendo desde un nombre, y el nombre no existe localmente, intentará buscar el nombre en cualquier ámbito que contenga (por ejemplo, el ámbito global del módulo).

Cuando se 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 recolectado en basura cuando func1() devuelve; mientras tanto, func2() nunca puede ver nada más que el nombre global (sin modificar). Tenga en cuenta que esta decisión de espacio de nombres ocurre en tiempo de compilación, no en tiempo de ejecución if si tuviera que leer el valor de myGlobal dentro de func1() antes de asignarlo, obtendría un UnboundLocalError, porque Python ya ha decidido que debe ser una variable local, pero aún no ha tenido ningún valor asociado con ella. Pero al usar la instrucción' global', le dices a Python que debería buscar en otro lugar el nombre 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 without 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 garantizar que el nombre no exista ya a nivel de módulo/builtin), lo que ralentizaría significativamente una operación muy común.)

 678
Author: Jeff Shannon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-16 18:01:50

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

Cada módulo tiene su propia tabla de símbolos privada, que es utilizada 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 choques accidentales con las variables globales de un usuario. Por otro lado, si sabes lo que estás haciendo puedes toque las variables globales de un módulo con la misma notación utilizada para referirse a sus funciones, modname.itemname.

Un uso específico de global-in-a-module se describe aquí - how-do-i-share-global-variables-across-modules, y 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 módulos de su aplicación; el módulo estará disponible como un nombre global. Debido a que 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
 180
Author: gimel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-24 12:07:01

Python utiliza una heurística simple para decidir desde qué ámbito debe cargar una variable, entre local y global. Si un nombre de variable aparece en el lado izquierdo de una asignación, pero no se declara global, se asume que es local. Si no aparece en el lado izquierdo de una asignación, se supone que ser 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 asignación en foo(), es la única variable LOAD_FAST.

 76
Author: SingleNegationElimination,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-12 12:35:08

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 de las funciones en las que se define esta función, se busca entre las variables globales.

Sin embargo, si asigna a una nueva variable no declarada como global en la función, es implícitamente declarado como local, y puede eclipsar cualquier variable global existente con el mismo nombre.

Además, las variables globales son útiles, contrariamente a algunos fanáticos de OOP que afirman lo contrario, especialmente para scripts más pequeños, donde OOP es excesivo.

 50
Author: J S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-04 22:00:48

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 asume que es un local . Si una variable siempre se asigna 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 consideración de un momento explica este. Por un lado, requerir global para las variables asignadas proporciona una barra contra efectos secundarios no deseados. Por otra parte, si global era requerido para todas las referencias globales, estaría utilizando global todos los tiempo. Tendrías que declarar como global cada referencia a un built-in función o a un componente de un módulo importado. Este desorden sería derrota de la utilidad de la declaración mundial para identificar efectos secundarios.

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

 38
Author: Rauni Lillemets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-20 10:36:29

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. Así que llamamos a la función create_global_variable:

>>> create_global_variable()

Usando globales sin modificación

Puedes usarlo, siempre y cuando no esperes cambiar a qué objeto apunta: {[18]]}

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 apuntar la variable global a un objeto diferente, se requiere que use la palabra clave global de nuevo:

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 la cambia aún no se ha ejecutado:

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

Así que después de llamar a la función:

>>> change_global_variable()

Podemos ver que la variable global ha cambiado. El nombre global_variable 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 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, 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 tal razón.

 32
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-20 16:32:18

Con la ejecución en paralelo, las variables globales pueden causar resultados inesperados si no entiende lo que está sucediendo. Aquí hay un ejemplo de 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]
 29
Author: Bohdan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-03 02:34:20

Necesita hacer referencia a la variable global en cada función que desee usar.

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]
"""
 20
Author: Mohamed El-Saka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-04 18:45:42

Lo que estás diciendo es usar el método de esta manera:

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 la misma salida.

 20
Author: gxyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-24 06:25:26

Resulta que la respuesta es siempre simple.

Aquí hay un pequeño módulo de muestra con una forma simple de mostrarlo en una definición main:

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

Aquí está cómo mostrarlo en una definición main:

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()

Este código simple funciona así, y se ejecutará. Espero que ayude.

 19
Author: user2876408,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-28 11:34:54

En realidad no está almacenando el global en una variable local, simplemente 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 tiene que especificar explícitamente cuándo un identificador debe referirse a un global predefinido, entonces presumiblemente tendrá 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.

podría tener un lenguaje que intentara adivinar, usando una variable global si existiera o creando una variable local si no existiera. Por ejemplo, la importación de otro módulo podría introducir inadvertidamente un variable con ese nombre, cambiando el comportamiento de su programa.

 18
Author: Kylotan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-30 21:09:51

Prueba esto:

def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7
 15
Author: Sagar Mehta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-20 21:55:48

Siguiendo y como complemento, use un archivo para contener todas las variables globales todas declaradas localmente y luego 'importar como':

Archivo initval.py

Stocksin = 300
Prices = []

Archivo getstocks.py

import  initval as  iv

Def   getmystocks (): 
     iv.Stocksin  = getstockcount ()


Def getmycharts ():
    For ic in range (0,iv.Stocksin):

.....

 12
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-04 22:03:12

Escribir a elementos explícitos de una matriz global aparentemente no necesita la declaración global, aunque escribirle "al por mayor"sí tiene ese requisito:

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix
 11
Author: Mike Lampton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-08 22:35:22

En caso de que tenga una variable local con el mismo nombre, es posible que desee utilizar la globals() function .

globals()['your_global_var'] = 42
 9
Author: Martin Thoma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-07 19:15:55

Haga referencia al espacio de nombres de clase donde desea que aparezca el cambio.

En este ejemplo, runner está usando max desde la configuración del archivo. Quiero que mi prueba cambie el valor de max cuando runner lo esté usando.

Main/config.py

max = 15000

Main/runner.py

from main import config
def check_threads():
    return max < thread_count 

Tests/runner_test.py

from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()
 5
Author: llewellyn falco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-19 08:48:27

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 función globals () devuelve un diccionario de símbolos globales mutables donde puedes "mágicamente" hacer que los datos estén disponibles para el resto de tu código. Por ejemplo:

from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

Y

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

Simplemente le permitirá volcar/cargar variables desde y hacia el espacio de nombres global. Super conveniente, sin problemas, sin alboroto. Estoy bastante seguro de que solo es Python 3.

 5
Author: Rafaël Dera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-05 14:59:14