2009-04-13 18 views
4

foo.py:Pythonでのインポートは静的な解決方法ですか?

i = 10 

def fi(): 
    global i 
    i = 99 

がbar.py:

import foo 
from foo import i 

print i, foo.i 
foo.fi() 
print i, foo.i 

これには問題があります。 foo.iが変更されたときにiが変更されないのはなぜですか?

+0

出力は次のとおりです。10 10 \ n 10 99 –

+0

質問は本当に明確ではありません。ちょうどfoo.iを使用して、正確に何が問題なのですか?怠惰? – hasen

+0

これはかなり初心者の質問です。彼はfoo.fi()を呼び出した後、私が99になることを望んでいます。彼が欠いているのはモジュールの実行だと私は思う。 +1を中和する。 –

答えて

7

foo.pyモジュールの名前空間のiと呼ばれる識別子と同じアドレスを指すbar.pyモジュールの名前空間でiと呼ばれる識別子を設定しています。

これは...重要な違いですbar.iはなく、むしろ、オブジェクト10foo.iが同時に指すように起こることを保持するメモリ内の同じスペースに、foo.iを指していません。 Pythonでは、変数名はメモリ空間ではありません。メモリ空間を指す識別子です。 barでインポートすると、ローカルの名前空間識別子を設定しています。

コードはfoo.fi()が呼び出されるまでfoo.py名前空間の識別子iが明らかに今10とは異なる場所モジュールのメモリ内のオブジェクトであるリテラル99、を指すように変更されたときに、予想通りに振る舞いますfooの-level namespace dictには、iがあり、bar.pyの識別子iとは異なるメモリを識別します。

シェーンとrossfabricantは、あなたが望むものを達成するためにモジュールを調整する方法についての良い提案をしています。 foo.py内部

0

グローバル変数を参照する代わりに関数を呼び出すことができます。ロスが言っている何

8

はそうのようなFOOをrestuctureすることです:

_i = 10 

def getI(): 
    return _i 

def fi(): 
    global _i 
    _i = 99 

次に、あなたはそれがあなたが望むように動作します表示されます。

>>> import foo 
>>> print foo.getI() 
10 
>>> foo.fi() 
>>> print foo.getI() 
99 

それはまた意味で「より良い」ですグローバルにエクスポートすることは避けられますが、引き続き読み込みアクセスを提供します。 bar.pyに何import

3

ibar.py内の1つから異なるiあります。 bar.pyにあなたが行うと:

foo.pyiと同じオブジェクトを参照すること bar.pyで新しい iを作成
from foo import i 

あなたの問題がある:あなたはfoo.fi()を呼び出し、それがいることをした場合:

i = 99 

割り当てが別の整数オブジェクト(99)にfoo.pyiポイントを作ること。整数オブジェクトは自分自身(不幸なことに)不変なので、foo.pyiが指しているものだけを変更します。bar.pyiではありません。 bar.pyiは、まだ前に指していた古いオブジェクトを指しています。

(不変オブジェクト10整数)あなたはbar.pyで次のコマンドを配置することによって、私が何を言っているかテストすることができます。

print foo.i 

それは99を印刷する必要があります。

+0

いい説明。 –

関連する問題