Reputation: 14988
main.py:
from module import *
var=10
def func2():
print "func2:" ,var
def main():
global var
var=20
print "main - before", var
func2()
func1()
print "main - after", var
if __name__=='__main__':
main()
module.py
from main import *
def func1():
global var
print "func1:", var
The program prints:
main - before: 20
func2: 20
func1: 10
main - after 20
'var' is a global variable. I would expect that the moment I change var's value, it will be changed wherever the variable 'var' appears. The only difference between func1 and func2 is that func1 is in another module. Still, I don't understand why the value of 'var' is different between func1 and func2.
Upvotes: 4
Views: 12381
Reputation: 77337
There is no such thing as a truly global variable in python. Objects are bound to variables in namespaces and the global
keyword refers to the current module namespace. from somemodule import *
creates new variables in the current module's namespace and refers them to somemodule's objects. You now have two different variables pointing to the same object. If you rebind one of the variables, the other ones continue to reference the original object. Further, a function.s "global" namespace is the module it is defined in, even if it is imported to a different module.
If you want a "global" variable, import the module and use its namespace qualified name instead of rebinding individual variables in the local namespace.
Here's an annotated example...
cfg.py
var = 10
somelist = []
var2 = 1
def show_var2():
print var2
main.py
import cfg
from cfg import * # bind objects referenced by variables in cfg to
# like-named variables in this module. These objects
# from 'cfg' now have an additional reference here
if __name__ == '__main__':
print cfg.var, var
var = 20 # rebind this module's 'var' to some other value.
# this does not affect cfg's 'var'
print cfg.var, var
print '----'
print cfg.somelist, somelist
somelist.append(1) # update this module's 'somelist'
# since we updated the existing object, all see it
print cfg.somelist, somelist
print '----'
var2 = 2
print var2, cfg.var2, show_var2() # show_var2 is in cfg.py and uses its
# namespace even if its been imported
# elsewhere
Upvotes: 5