2016-08-05 4 views
4

最近、私はこの例を設定し、結果に驚いています。私は、コードでこれを実証します:Pythonマルチモジュールのグローバル変数。 Pythonのバグ?

はFile1:b.py

delta = 0.0 

def example(): 
    global delta 

    delta = 1 

def ret_delta(): 
    return delta 

File2の:a.py

from b import * 

example() 

#WHY ARE THESE DIFFERENT? 
print(delta) # prints: 0.0 
print(ret_delta()) # prints: 1 

これは意味がありません!なぜ変数にアクセスし、その変数を返す関数を呼び出すのが違いになるのでしょうか?あなたの参考のために

私はあなたがa.py

from b import *

を行うと、それは(delta含む)モジュールbで定義されたすべての名前をインポートWindowsの32ビット

+0

'from b import *'は悪い形式です(この状況で何が起こるのか不明瞭な理由の1つです)。代わりに 'import b'を考えて、' b.delta'を代わりに使ってください。これはどちらも明示的ですが、_and_は実際に期待どおりに動作します。 – marcelm

答えて

5

でPython 3.5.2を使用していますaさんの名前空間に追加してください。 Pythonで不変タイプでfloatとして、あなたは別の値を指し、b.deltaからa.delta完全に別の変数を考慮することができます。 秒b.deltaの更新された値を出力しつつ、第一print()は、a.deltaの初期値を出力します。

+0

ありがとう、それはそれを説明するようだ! –

2

from b import *は、あなたのaモジュールグローバルにおける新しい参照のシリーズを作成します。それらの各々はbの参照をコピーします。しかし、彼らは独立系グローバルです。

Pythonで、名前は単にラベルであることを忘れないでください。それらはオブジェクトに「結びついている」。この関係は割当によって登録し、オブジェクトごとに複数のラベルを登録することができます。ここでは、bにラベルがあり、aにラベルがあり、from b import *の後に、両方のモジュールのラベルに同じオブジェクトが参照されています。

異なるオブジェクトをのdeltaという名前に割り当てます。そのラベルはもはや古い0.0 floatオブジェクトを参照していません。しかし、あなたはadeltaラベルが縛られているものを変更しませんでした。

名前の前にモジュール名を付けると、a.deltab.deltaが得られます。割り当てb.delta = 1a.delta変更しないだろう、彼らは異なる名前空間に住んでいます。

あなたは、Pythonの名前がどのように機能するかをよく読んですることをお勧めします。 Ned Batchelder著優れたFacts and myths about Python names and values presentationを参照してください。

+0

答えのあなたの句は私を混乱させる。 |で、およびfrom b importの後では、bからの同じオブジェクト|を参照します。そうですか? –

+0

@EkeymeMo:私はあなたのコメントに従うかどうかはわかりません、ごめんなさい。 –

+0

申し訳ありません、私の以前のコメントは電話で書かれていますが、ハイライトのfeatrueは挿入できません。あなたの答えでは、あなたが言うことは、「... bからのインポート* ...」であると思います。そうですか? –

関連する問題