Variables globales de la función de Python?

Sé que debo evitar el uso de variables globales en primer lugar debido a una confusión como esta, pero si las utilizara, ¿es la siguiente una forma válida de utilizarlas? (Estoy intentando llamar a la copia global de una variable creada en una función separada).

x = somevalue def func_A (): global x # Do things to x return x def func_B(): x=func_A() # Do things return x func_A() func_B() 

¿La x que usa la segunda función tiene el mismo valor que la copia global de x que func_a usa y modifica? Al llamar a las funciones después de la definición, ¿el orden importa?

Si desea acceder simplemente a una variable global, simplemente use su nombre. Sin embargo, para cambiar su valor, debe utilizar la palabra clave global .

P.ej

 global someVar someVar = 55 

Esto cambiaría el valor de la variable global a 55. De lo contrario, solo asignaría 55 a una variable local.

El orden de las listas de definición de funciones no importa (suponiendo que no se refieran entre sí de alguna manera), el orden en que se llaman sí lo hace.

Dentro de un scope de Python, cualquier asignación a una variable que aún no se haya declarado dentro de ese scope crea una nueva variable local, a menos que esa variable se declare anteriormente en la función como referencia a una variable de scope global con la palabra clave global .

Veamos una versión modificada de su pseudocódigo para ver qué sucede:

 # Here, we're creating a variable 'x', in the __main__ scope. x = 'None!' def func_A(): # The below declaration lets the function know that we # mean the global 'x' when we refer to that variable, not # any local one global x x = 'A' return x def func_B(): # Here, we are somewhat mislead. We're actually involving two different # variables named 'x'. One is local to func_B, the other is global. # By calling func_A(), we do two things: we're reassigning the value # of the GLOBAL x as part of func_A, and then taking that same value # since it's returned by func_A, and assigning it to a LOCAL variable # named 'x'. x = func_A() # look at this as: x_local = func_A() # Here, we're assigning the value of 'B' to the LOCAL x. x = 'B' # look at this as: x_local = 'B' return x # look at this as: return x_local 

De hecho, podría volver a escribir todo func_B con la variable llamada x_local y funcionaría de manera idéntica.

El orden solo importa en cuanto al orden en el que sus funciones realizan operaciones que cambian el valor del x global. Así, en nuestro ejemplo, el orden no importa, ya que func_B llama func_A . En este ejemplo, el orden sí importa:

 def a(): global foo foo = 'A' def b(): global foo foo = 'B' b() a() print foo # prints 'A' because a() was the last function to modify 'foo'. 

Tenga en cuenta que global solo es necesario para modificar objetos globales. Aún puede acceder a ellos desde dentro de una función sin declarar global . Por lo tanto, tenemos:

 x = 5 def access_only(): return x # This returns whatever the global value of 'x' is def modify(): global x x = 'modified' return x # This function makes the global 'x' equal to 'modified', and then returns that value def create_locally(): x = 'local!' return x # This function creates a new local variable named 'x', and sets it as 'local', # and returns that. The global 'x' is untouched. 

Tenga en cuenta la diferencia entre create_locally y access_only : access_only está accediendo al x global a pesar de no llamar a global , y aunque create_locally tampoco usa el global , crea una copia local ya que asigna un valor.

La confusión aquí es por qué no debes usar variables globales.

Como han señalado otros, debe declarar una variable global en una función cuando desee que esa función pueda modificar la variable global. Si solo quieres acceder a él, entonces no necesitas global .

Para profundizar un poco más en eso, lo que significa “modificar” es esto: si desea volver a enlazar el nombre global para que apunte a un objeto diferente, el nombre debe ser declarado global en la función.

Muchas operaciones que modifican (mutan) un objeto no vuelven a unir el nombre global para que apunte a un objeto diferente, por lo que todas son válidas sin declarar el nombre global en la función.

 d = {} l = [] o = type("object", (object,), {})() def valid(): # these are all valid without declaring any names global! d[0] = 1 # changes what's in d, but d still points to the same object d[0] += 1 # ditto d.clear() # ditto! d is now empty but it`s still the same object! l.append(0) # l is still the same list but has an additional member o.test = 1 # creating new attribute on o, but o is still the same object 

Aquí hay un caso que me llamó la atención, usando un valor global como valor predeterminado de un parámetro.

 globVar = None # initialize value of global variable def func(param = globVar): # use globVar as default value for param print 'param =', param, 'globVar =', globVar # display values def test(): global globVar globVar = 42 # change value of global func() test() ========= output: param = None, globVar = 42 

Esperaba que param tuviera un valor de 42. Sorpresa. Python 2.7 evaluó el valor de globVar cuando analizó por primera vez la función func. Cambiar el valor de globVar no afectó el valor predeterminado asignado a param. Retrasar la evaluación, como en el siguiente, funcionó como lo necesitaba.

 def func(param = eval('globVar')): # this seems to work print 'param =', param, 'globVar =', globVar # display values 

O, si quieres estar seguro,

 def func(param = None)): if param == None: param = globVar print 'param =', param, 'globVar =', globVar # display values 

Debe utilizar la statement global cuando desee modificar el valor asignado a una variable global.

No es necesario que lo lea desde una variable global. Tenga en cuenta que llamar a un método en un objeto (incluso si altera los datos dentro de ese objeto) no altera el valor de la variable que contiene ese objeto (ausencia de magia reflexiva).

Puede acceder directamente a una variable global dentro de una función. Si desea cambiar el valor de esa variable global, use “global variable_name”. Vea el siguiente ejemplo:

 var = 1 def global_var_change(): global var var = "value changed" global_var_change() #call the function for changes print var 

En general, esta no es una buena práctica de progtwigción. Al romper la lógica del espacio de nombres, el código puede ser difícil de entender y depurar.