问题
Just confused about global value in Python, here are two piece of code
#gl.py
import cli
a = 1
print "gl 1: %d %d" % (id(a), a)
def reset():
global a
a = 7
print "reset 1: %d %d" % (id(a), a)
if __name__ == '__main__':
cli.handler(reset)
print "gl 2: %d %d" % (id(a), a)
the cli code
#cli.py
def handler(func):
from gl import a
print "cli 1: %d %d" % (id(a), a)
func()
print "cli 2: %d %d" % (id(a), a)
The result of execution is
$ python gl.py
gl 1: 150847672 1
gl 1: 150847672 1
cli 1: 150847672 1
reset 1: 150847600 7
cli 2: 150847672 1 #Why value doesn't change
gl 2: 150847600 7
Here I don't understand after "function reset()" execution, the result of global value doesn't change in cli.py(cli 2: 150847672 1), but back to gl.py, global value does change!!
回答1:
Two concepts are missing here
- Globals are globals to modules and not across modules
Refer: http://legacy.python.org/doc/essays/ppt/hp-training/sld036.htm
Refer: http://docs.python.org/release/2.4/ref/global.html
- Variables are imported as Values and not by reference
Refer: https://stackoverflow.com/a/3338357/977038
If you need to share Global variables across modules refer How do I share global variables across modules?
回答2:
Your gl
module is imported twice into two different namespaces
try this:
import sys
print sys.modules['__main__'].a
print sys.modules['gl'].a
回答3:
The gl you import in cli is actually a copy of the module object. if we change your code like this:
#gl.py
import cli
import sys
a = 1
print "gl 1: %d %d" % (id(a), a)
print "gl id on import: {0}".format(id(sys.modules[__name__]))
def reset():
global a
a = 7
print "gl id in reset: {0}".format(id(sys.modules[__name__]))
print "reset 1: %d %d" % (id(a), a)
def printa():
print "gl: %d %d" % (id(a), a)
if __name__ == '__main__':
cli.handler(reset)
print "gl id in main: {0}".format(id(sys.modules[__name__]))
print "gl 2: %d %d" % (id(a), a)
and
#cli.py
def handler(func):
#from gl import a
import gl
print "gl id in cli: {0}".format(id(gl))
print "cli 1: %d %d" % (id(gl.a), gl.a)
func()
print "cli 2: %d %d" % (id(gl.a), gl.a)
gl.reset()
print "cli 3: %d %d" % (id(gl.a), gl.a)
We get:
gl 1: 19056568 1
gl id on import: 140075849968728
gl 1: 19056568 1
gl id on import: 20004096
gl id in cli: 20004096
cli 1: 19056568 1
gl id in reset: 140075849968728
reset 1: 19056424 7
cli 2: 19056568 1
gl id in reset: 20004096
reset 1: 19056424 7
cli 3: 19056424 7
gl id in main: 140075849968728
gl 2: 19056424 7
So when we run reset, we change the reference
a -> 19056568
to
a -> 19056424
but only in one gl copy. The other one (the one in cli) holds on to the old reference. If we run gl.reset() from within cli, the reference on that copy changes and we get the expected change in cli.
来源:https://stackoverflow.com/questions/15239783/why-reset-python-global-value-doesnt-take-effect