resueltos - Variables globales de la función de Python?
lista de funciones de python (6)
Aquí hay un caso que me sorprendió, 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
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?
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
Debe utilizar la declaración 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).
Dentro de un alcance de Python, cualquier asignación a una variable que aún no se haya declarado dentro de ese alcance crea una nueva variable local, a menos que esa variable se declare anteriormente en la función como referencia a una variable de alcance 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. Todavía puede acceder a ellos desde 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 a la x global a pesar de no llamar a global
, y aunque create_locally
tampoco usa global
, crea una copia local ya que asigna un valor.
La confusión aquí es por qué no debes usar variables globales.
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 programación. Al romper la lógica del espacio de nombres, el código puede ser difícil de entender y depurar.
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.