Problem
I know I should avoid using global variables in the first place because of issues like this, but is the following a valid method to utilize them if I do? (I’m trying to call a global duplicate of a variable that was generated in a different function.)
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()
Does the global copy of x that func a uses and alters have the same value as the x that the second function uses? Is it important to invoke the functions in the same sequence as they were defined?
Asked by Akshat Shekhar
Solution #1
You can just use the name of a global variable to access it. To modify its value, however, you must use the global keyword.
E.g.
global someVar
someVar = 55
This would alter the global variable’s value to 55. If not, it will just assign 55 to a local variable.
The order in which function definition listings are listed doesn’t matter (as long as they don’t refer to each other), but the order in which they are called matters.
Answered by Levon
Solution #2
Unless a variable is stated earlier in the function as referring to a globally scoped variable with the keyword global, every assignment to a variable not already declared within that scope produces a new local variable.
To illustrate what happens, let’s look at a modified version of your pseudocode:
# 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
In fact, you could rewrite all of func_B with the variable named x_local and it would work identically.
Only the sequence in which your functions perform operations that affect the value of the global x matters. Because func B invokes func A, the order doesn’t matter in our scenario. Order is important in this case:
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'.
It’s worth noting that global is only required when working with global objects. Without declaring global, you can still access them from within a function. As a result, we have:
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.
Note the difference between access only and create locally: access only accesses the global x while not calling global, and create locally, although not calling global, produces a local copy because it assigns a value.
The issue arises from the fact that global variables should not be used.
Answered by jdotjdot
Solution #3
When you want a function to be able to edit a global variable, as others have pointed out, you must declare the variable global in the function. You don’t require global if you merely wish to access it.
To clarify, “modify” means that if you want to re-bind the global name so that it points to a different object, the name must first be declared global in the function.
Because many actions that change (mutate) an object do not re-bind the global name to point to a different object, they are all acceptable even if the name global is not declared in the function.
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
Answered by kindall
Solution #4
Within a function, you can directly access a global variable. Use “global variable name” if you wish to update the value of that global variable. Consider the following scenario:
var = 1
def global_var_change():
global var
var = "value changed"
global_var_change() #call the function for changes
print var
This is not, in general, a good programming practise. Code might become difficult to comprehend and debug if namespace logic is broken.
Answered by Noisy_Botnet
Solution #5
Using a global as the default value of a parameter was one example that threw me off guard.
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
I had anticipated a value of 42 for param. Surprise. When Python 2.7 first parsed the function func, it assessed the value of globVar. The default value assigned to param was unaffected by changing the value of globVar. Delaying the evaluation, as seen below, worked perfectly for me.
def func(param = eval('globVar')): # this seems to work
print 'param =', param, 'globVar =', globVar # display values
Alternatively, if you want to be safe,
def func(param = None)):
if param == None:
param = globVar
print 'param =', param, 'globVar =', globVar # display values
Answered by SoloPilot
Post is based on https://stackoverflow.com/questions/10588317/python-function-global-variables