Why reset python global value doesn't take effect

我只是一个虾纸丫 提交于 2019-12-18 04:01:51

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!