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

preguntado el 08 de enero de 09 a las 03:01

20 Respuestas

Puede utilizar una variable global dentro de otras funciones declarándola como global dentro de cada función que le asigna un valor:

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 de esto es que, dado que las variables globales son tan peligrosas, Python quiere asegurarse de que realmente sepa que es con lo que está jugando al requerir explícitamente la global palabra clave.

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

Respondido 11 ago 20, 22:08

Es una exageración extrema referirse a los globales como "tan peligrosos". Los globales están perfectamente bien en todos los idiomas que han existido y existirán. Tienen su lugar. Lo que debería haber dicho es que pueden causar problemas si no tiene idea de cómo programar. - Antonio

Creo que son bastante peligrosos. Sin embargo, en Python, las variables "globales" son en realidad a nivel de módulo, lo que resuelve muchos problemas. - Fabio Santos

No estoy de acuerdo con que la razón por la que Python requiera el global La palabra clave se debe a que los globales son peligrosos. Más bien, es porque el lenguaje no requiere que declare explícitamente las variables y automáticamente asume que una variable que usted asigna tiene un alcance de función a menos que le indique lo contrario. La global La palabra clave es el medio que se proporciona para decirle lo contrario. - Nate CK

@avgvstvs: Y si está implementando el mismo programa sin globales, todavía tiene el mismo número de rutas de código. El argumento que ha presentado no es uno contra los globales. - Carreras de ligereza en órbita

@LightnessRacesinOrbit No entiendo tu punto. Si elimina una variable global, elimina el factor de complicación en eso ahora, las funciones arbitrarias ya no pueden alterar el estado del programa, en varios puntos de la ejecución, alterando así la ejecución de una manera que de otro modo sería imperceptible para otras funciones que dependen de esa variable. Ya no tienes que realizar un seguimiento de "Did f2() cambiar de estado así que ahora f3() ¿Podría hacer algo inesperado? Las funciones ahora pueden operar de forma independiente al estado del programa externo. - avgvstvs

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 tiene 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 en su lugar imprime 5. Como ya se ha mencionado, si agrega un 'global'declaración a func1(), entonces func2() imprimirá 42.

def func1():
    global myGlobal
    myGlobal = 42

Lo que sucede aquí es que Python asume que cualquier nombre que sea 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 es solo lectura a partir de un nombre, y el nombre no existe localmente, intentará buscar el nombre en cualquier ámbito que lo contenga (por ejemplo, el ámbito global del módulo).

Cuando asigna 42 al nombre myGlobal, por lo tanto, Python crea una variable local que oculta la variable global del mismo nombre. Ese local sale de alcance y es recogida de basura cuando func1() devoluciones; Entretanto, 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, si tuviera que leer el valor de myGlobal dentro 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. Pero al usar el 'global', le dice a Python que debe buscar el nombre en otro lugar en lugar de asignárselo localmente.

(Creo que este comportamiento se originó en gran parte a través de una optimización de los espacios de nombres locales; sin este comportamiento, la máquina virtual 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 a nivel de módulo / incorporado), lo que ralentizaría significativamente una operación muy común).

respondido 16 mar '15, 18:03

Mencionaste que la decisión del espacio de nombres ocurre en tiempo de compilación, No creo que sea cierto. de lo que aprendo la compilación de Python solo comprueba si hay errores de sintaxis, no errores de nombre prueba este ejemplo def A (): x + = 1, si no lo ejecuta, lo hará no dar UnboundLocalError, por favor verifique gracias - watashiSHUN

Es común usar una letra mayúscula para variables globales como MyGlobal = 5 - Vassilis

@watashiSHUN: La decisión del espacio de nombres suceden en tiempo de compilación. Decidiendo eso 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 usara por primera vez. - BlackJack

@Vassilis: es común usar mayúsculas todos letras: MY_GLOBAL = 5. Consulte las Guía de estilo para código Python. - BlackJack

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 todas las funciones definidas en el módulo utilizan como tabla de símbolos global. 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 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: ¿Cómo comparto variables globales entre módulos?, 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 or cfg). Simplemente importe el módulo de configuración en todos los módulos de su aplicación; el módulo pasa a 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

Respondido el 16 de diciembre de 20 a las 04:12

por una razón no me gusta el config.x ¿Puedo deshacerme de él? Yo vine con x = lambda: config.x y luego tengo el Un nuevo Valor en x(). por alguna razón, tener a = config.x no me hace el truco. - vladosaurio

@vladosaurus hace from config import x resolver eso? - jhyland

@vladosaurus uso from config import x - psicozander

Python usa una heurística simple para decidir desde qué ámbito debe cargar una variable, entre local y global. Si el nombre de una 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 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.

Respondido 12 Jul 11, 13:07

La heurística busca operaciones vinculantes. La asignación es una de esas operaciones, la importación de otra. Pero el objetivo de un for bucle y el nombre después as in with y except las declaraciones también están vinculadas a. - Martijn Pieters ♦

@MartijnPieters Para el nombre después as en una except cláusula que esto no era obvio para mí. Pero se borra automáticamente para ahorrar memoria. - Robert

@Robert: no para ahorrar memoria, sino para evitar crear una referencia circular, que puede provocar pérdidas de memoria. Esto se debe a que una excepción hace referencia a un rastreo, y el rastreo hace referencia a cada espacio de nombres local y global a lo largo de toda la pila de llamadas, incluido el as ... target en el manejador de excepciones. - Martijn Pieters ♦

Si desea hacer referencia a una variable global en una función, puede usar la global palabra clave 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 alcance local o en los alcances en las funciones en las que se define esta función, se busca entre global 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, contrariamente a algunos fanáticos de OOP que afirman lo contrario, especialmente para scripts más pequeños, donde OOP es excesivo.

respondido 04 mar '17, 22:03

Absolutamente re. fanáticos. La mayoría de los usuarios de Python lo utilizan para la creación de scripts y crean pequeñas funciones para separar pequeños fragmentos de código. - Pablo Uszak

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()

Usando globales sin modificaciones

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

Por ejemplo, los servicios administrativos de

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

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

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

>>> change_global_variable()

podemos ver que se ha cambiado la variable global. La global_variable el nombre ahora apunta a 'Bar':

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

Tenga en cuenta que "global" en Python no es verdaderamente 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, 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:

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 el uso de esa variable local mal nombrada no cambia la variable global:

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

Tenga en cuenta que debe evitar el uso de variables locales con los mismos nombres que 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.

Obtenemos el mismo comportamiento en las clases.

Un comentario de seguimiento pregunta:

¿Qué hacer si quiero crear una variable global dentro de una función dentro de una clase y quiero usar esa variable dentro de otra función dentro de otra clase?

Aquí demuestro que obtenemos el mismo comportamiento en los métodos que en las funciones regulares:

class Foo:
    def foo(self):
        global global_variable
        global_variable = 'Foo'

class Bar:
    def bar(self):
        return global_variable + '!!!'

Foo().foo()

Y ahora:

>>> Bar().bar()
'Foo!!!'

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 se cambia el atributo de clase del habitual cls argumento) o métodos estáticos (no self or cls).

Respondido el 19 de enero de 20 a las 14:01

Genial, pero ¿qué hacer si quiero crear una variable global dentro de una función dentro de una clase y quiero usar esa variable dentro de otra función dentro de otra clase? Un poco atrapado aquí fpaekoaij

@anonmanx No sé por qué estás atascado, es el mismo comportamiento en un método que en una función normal. Pero actualizaré mi respuesta con su comentario y algún código de demostración, ¿de acuerdo? - Aaron Hall ♦

Ok, lo tengo. Entonces tendré que llamar explícitamente a esa función para usar esa variable global. - fpaekoaij

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 locales. Si a una variable se le asigna un nuevo valor dentro de la función, la variable es implícitamente local y debe declararla explícitamente como 'global'.

Aunque un poco sorprendente al principio, un momento de consideración lo explica. Por un lado, requerir global para las variables asignadas proporciona una barrera contra los efectos secundarios no deseados. Por otro lado, si se requiriera global para todas las referencias globales, estaría utilizando global todo el tiempo. Tendría que declarar como global cada referencia a una función incorporada oa un componente de un módulo importado. Este desorden frustraría 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?.

Respondido 20 Jul 14, 11:07

Con la ejecución en paralelo, las variables globales pueden causar resultados inesperados si no comprende lo que está sucediendo. A continuación se muestra un ejemplo del uso de una variable global dentro del multiprocesamiento. Podemos ver claramente que cada proceso trabaja 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]

Respondido el 03 de enero de 17 a las 02:01

Resulta que la respuesta siempre es simple.

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

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

def isTheNumber():
    return helper

A continuación se explica cómo mostrarlo en un main definición:

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.

Respondido el 28 de Septiembre de 18 a las 12:09

gracias, soy nuevo en Python, pero sé un poco de Java. lo que dijiste funcionó para mí. y escribiendo un global a dentro de la clase ... parece tener más sentido para mí que dentro de una función escribiendo 'global a' ... Me doy cuenta de que no puedes decir global a = 4 - barlop

Este es probablemente el truco de Python más simple pero muy útil para mí. Yo nombro este módulo global_varse inicializar los datos en init_global_vars, que se llama en el script de inicio. Luego, simplemente creo un método de acceso para cada var global definida. ¡Espero poder votar a favor de esto varias veces! ¡Gracias Peter! - swdev

¿Qué sucede si hay muchas variables globales y no quiero tener que enumerarlas una por una después de una declaración global? - jtlz2

Lo que está 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:

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

Ambos dan el mismo resultado.

Respondido el 01 de diciembre de 20 a las 07:12

Este segundo ejemplo me da "NameError: el nombre 'globvar' no está definido" en Python3.7 - Pim Heijden

Pim: debería funcionar ahora, error tipográfico fijo: s / globavar / globvar / - D McKeon

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]
"""

Respondido 04 Feb 15, 18:02

'en cada función que desea usar' es sutilmente incorrecto, debería estar más cerca de: 'en cada función donde desea actualización'- espasmo

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 prácticamente 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 hacer referencia a un global predefinido, entonces presumiblemente tendría que especificar explícitamente cuándo un identificador es una nueva variable local en su lugar (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 intentó adivinar, usando una variable global si existía o creando una variable local si no existía. 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.

contestado el 30 de mayo de 11 a las 22:05

Prueba esto:

def x1():
    global x
    x += 1
    print('x1: ', x)

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

x = 5
print('x:  ', x)
x1()
x2()

# Output:
# x:   5
# x1:  6
# x2:  7

respondido 27 nov., 20:17

¡Felicidades! Finalmente alguien que obtuvo el punto más importante de usar global. Es decir, usar una variable en una función que se definió después de la función en sí. - no2qubit

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

globals()['your_global_var'] = 42

Respondido 07 Abr '17, 20:04

A continuación y como complemento, use un archivo para contener todas las variables globales, todas declaradas localmente y luego import as:

Declarar impuestos initval.py:

Stocksin = 300
Prices = []

Declarar impuestos getstocks.py:

import initval as iv

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


def getmycharts():
    for ic in range(iv.Stocksin):

contestado el 21 de mayo de 19 a las 11:05

¿Cuál es la ventaja de mover las variables globales a otro archivo? ¿Es solo para agrupar las variables globales en un archivo pequeño? Y por qué usar la declaración import ... as ...? Porque no solo import ...? - oho

Ah ... finalmente he entendido la ventaja: no es necesario utilizar la palabra clave global :-) => +1 :-) Edite su respuesta para aclarar estos interrogatorios que otras personas también pueden tener. Salud - oho

Escribir 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:

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

Respondido el 08 de enero de 16 a las 22:01

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

En este ejemplo, el corredor está usando max desde el archivo config. Quiero que mi prueba cambie el valor de max cuando el corredor 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()

Respondido 19 ago 17, 09:08

Estoy agregando esto porque no lo he visto en ninguna de las otras respuestas y podría ser útil para alguien que esté luchando con algo similar. La globals() La 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:

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

Le permitirá volcar / cargar variables fuera y dentro del espacio de nombres global. Súper conveniente, sin despeinarse, sin problemas. Estoy bastante seguro de que es solo Python 3.

contestado el 21 de mayo de 19 a las 13:05

globals() siempre devuelve globales disponibles en el contexto local, por lo que una mutación aquí puede no reflejarse en otro módulo. - Kiran Jonnalagadda

Los globales están bien, excepto con multiprocesamiento

Los aspectos globales relacionados con el multiprocesamiento en diferentes plataformas / entornos como Windows / Mac OS por un lado y Linux por el otro son problemáticos.

Les mostraré esto con un ejemplo simple que señala un problema con el que me encontré hace algún tiempo.

Si desea comprender por qué las cosas son diferentes en Windows / MacOs y Linux, debe saber eso, el mecanismo predeterminado para iniciar un nuevo proceso en ...

  • Windows / MacOs es 'spawn'
  • Linux es 'bifurcación'

Son diferentes en la asignación de memoria y la inicialización ... (pero no entro en esto aquí).

Echemos un vistazo al problema / ejemplo ...

import multiprocessing

counter = 0

def do(task_id):
    global counter
    counter +=1
    print(f'task {task_id}: counter = {counter}')

if __name__ == '__main__':

    pool = multiprocessing.Pool(processes=4)
    task_ids = list(range(4))
    pool.map(do, task_ids)

Ventanas

Si ejecuta esto en Windows (y supongo que también en MacOS), obtendrá el siguiente resultado ...

task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4

Linux

Si ejecuta esto en Linux, obtendrá lo siguiente.

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1

contestado el 24 de mayo de 20 a las 22:05

Hay 2 formas de declarar una variable como global:

1. Asignar funciones internas de variable y usar la línea global

def declare_a_global_variable():
    global global_variable_1
    global_variable_1 = 1

# Note to use the function to global variables
declare_a_global_variable() 

2. Asignar funciones externas variables:

global_variable_2 = 2

Ahora podemos usar estas variables globales declaradas en las otras funciones:

def declare_a_global_variable():
    global global_variable_1
    global_variable_1 = 1

# Note to use the function to global variables
declare_a_global_variable() 
global_variable_2 = 2

def print_variables():
    print(global_variable_1)
    print(global_variable_2)
print_variables() # prints 1 & 2

Nota 1:

Si desea cambiar una variable global dentro de otra función como update_variables() debe usar la línea global en esa función antes de asignar la variable:

global_variable_1 = 1
global_variable_2 = 2

def update_variables():
    global global_variable_1
    global_variable_1 = 11
    global_variable_2 = 12 # will update just locally for this function

update_variables()
print(global_variable_1) # prints 11
print(global_variable_2) # prints 2

Nota 2:

Hay una excepción para la nota 1 para las variables de lista y diccionario cuando no se usa una línea global dentro de una función:

# declaring some global variables
variable = 'peter'
list_variable_1 = ['a','b']
list_variable_2 = ['c','d']

def update_global_variables():
    """without using global line"""
    variable = 'PETER' # won't update in global scope
    list_variable_1 = ['A','B'] # won't update in global scope
    list_variable_2[0] = 'C' # updated in global scope surprisingly this way
    list_variable_2[1] = 'D' # updated in global scope surprisingly this way

update_global_variables()

print('variable is: %s'%variable) # prints peter
print('list_variable_1 is: %s'%list_variable_1) # prints ['a', 'b']
print('list_variable_2 is: %s'%list_variable_2) # prints ['C', 'D']

Respondido el 12 de Septiembre de 20 a las 10:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.