对于Python中的全局价值感到困惑,这里有两段代码
#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)
cli代码
#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)
执行结果是
$ 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
这里我不明白“function reset()”执行后,全局值的结果在cli.py( cli 2:150847672 1 )中没有变化,但是回到gl .py,全球价值确实在变化!!
答案 0 :(得分:4)
这里缺少两个概念
参考:http://legacy.python.org/doc/essays/ppt/hp-training/sld036.htm
参考:http://docs.python.org/release/2.4/ref/global.html
参考:https://stackoverflow.com/a/3338357/977038
如果您需要跨模块共享全局变量,请参阅How do I share global variables across modules?
答案 1 :(得分:2)
您的gl
模块被导入两次到两个不同的命名空间
试试这个:
import sys
print sys.modules['__main__'].a
print sys.modules['gl'].a
答案 2 :(得分:2)
您在cli中导入的gl实际上是模块对象的副本。 如果我们改变你的代码:
#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)
和
#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)
我们得到:
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
因此,当我们运行重置时,我们会更改引用
a -> 19056568
到
a -> 19056424
但仅限于一份副本。另一个(cli中的那个)坚持旧的参考。 如果我们从cli中运行gl.reset(),那么该副本上的引用会发生变化,我们会得到cli的预期变化。