2013-03-06 1 views
11

になりませんなぜ、ここにコードリセットパイソングローバル値は、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に戻って、グローバルな価値は変化します!!

+2

インポートを 'import gl'に変更し、' a'を 'gl.a'と変更してください。グローバル変数は 'gl'モジュールに関してのみグローバルです。インポートによってローカルコピーが作成されます。 –

+0

@スティーブン私はあまりにも思ったが、簡単なテストではそうではないことが示されている。比較的新しいユーザーからの良い、面白い質問 - 歓迎! – Voo

+0

しかし、それはなぜ変わらなければならないのですか?あなたはa = 1をインポートしています。それは印刷されています1.ちょっと試してみましょう。これらの全体はMark Lutzの最初の部分で "Begging with python"やそれと同じものがあります。 – Denis

答えて

2

あなたglモジュールは、2つの異なる名前空間に二回インポートされ

これを試してみてください。

import sys 
print sys.modules['__main__'].a 
print sys.modules['gl'].a 
4

2つの理念が、ここで欠けている

  • グローバルモジュールにグローバルであるといないモジュール
  • 渡っ

参照: 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?

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 

ただし、1つのglコピーのみです。もう1つ(cliのもの)は古い参照を保持します。 cli内からgl.reset()を実行すると、そのコピーの参照が変更され、cliで期待される変更が得られます。

関連する問題