2012-05-08 10 views
40

私はPythonで作品をインポートする方法を理解していない2つの特定の状況があります。Pythonのインポートはどのように機能しますか?

第一の特定の状況:

私は2つの異なったPythonスクリプトで同じモジュールをインポートすると、モジュールではありませんが二度輸入されましたか? Pythonが最初にそれを見つけたとき、それはインポートされ、2回目に、モジュールがインポートされたかどうか、またはコピーが作成されるかどうかがチェックされますか?

第二の特定の状況:

には、以下のモジュールを考慮し、bla.py呼ば:

a = 10 

をそして、我々は、bla.pyインポートモジュールfoo.pyあります

from bla import * 

def Stuff(): 
    return a 

とをその後、というスクリプトがありますユーザーによって実行されます、:

ここ
from foo import * 
Stuff() #This should return 10 
a = 5 
Stuff() 

私は知らない:Stuff()復帰10または5をしていますか?

+12

コードを実行するとどうなりましたか? – geoffspear

+0

あなたはこれらの面白いかもしれません:http://lucumr.pocoo.org/2011/9/21/python-import-blackbox/とhttp://lucumr.pocoo.org/2009/7/24/singletons-and-彼らの問題は - python /で。彼らは両方ともPythonでのインポートを扱います。 – rubik

答えて

50

パート1

モジュールは一度だけロードされているので、それを再度インポートしても、パフォーマンスの損失はありません。実際に再度ロード/解析するには、reload()モジュールが必要です。

チェックされた最初の場所は、以前にインポートされたすべてのモジュールのキャッシュsys.modulesです。 [source]


第2

from foo import *輸入ローカルスコープにaaに値を代入すると、新しい値に置き換えられますが、元のfoo.a変数には触れません。

import fooを除き、foo.aを変更すると、両方の呼び出しが同じ値を返します。

リストや辞書などの変更可能なタイプの場合は、それが実際の変数に影響を与えるように変更することができますが、新しい値を割り当てるとまだfoo.whateverは変更されません。

あなたには、いくつかのより詳細な情報が必要な場合は、持っているhttp://docs.python.org/reference/executionmodel.htmlを見て:

以下の構築物が名前をバインド:関数への仮パラメータ、import文を、クラスや関数の定義(これらは、クラスをバインドしますか定義ブロックの関数名)、および、ループヘッダー、except節のヘッダーの2番目の位置、またはwithステートメントの後に出現する場合は識別子であるターゲット。

2つの太字のセクションでは、あなたのために、関連するものです。まず名前aは、インポート時にfoo.aの値にバインドされています。次に、a = 5を実行すると、aという名前は5にバインドされます。リスト/ディクテーションを変更してもバインディングが発生しないため、これらの操作は元のオブジェクトを変更します(bおよびfoo.bは、操作対象と同じオブジェクトにバインドされています)。新しいオブジェクトをbに割り当てることは、再度バインディング操作になるため、bfoo.bから分離します。

また、正確import文が何をするか注目に値する:

  • import fooは、現在のスコープ内のモジュールオブジェクトにモジュール名を結合し、あなたがfoo.whateverを変更した場合、あなたはそれに名前で動作しますモジュール - 変更/割り当ては、モジュール内の変数に影響します。
  • from foo import barfooで同じ名前の要素に与えられた名前(複数可)のみ(即ちfooが結合していないままであろう)に結合する - 操作ようbar上のように振る舞う以前説明しました。
  • from foo import *は前のように動作しますが、接頭辞がアンダースコアではないすべてのグローバル名がインポートされます。モジュールが__all__を定義する場合、このシーケンス内の名前のみがインポートされます。

パート3(でも、あなたの質問に存在しません:P)

Pythonドキュメントは通常、冗長極めて良好であり、 - あなたは、ほぼすべての可能な言語関連の上の答えを見つけますそこの質問。便利なリンクは次のとおりです。

2

最初の質問にお答えします:

いいえ、Pythonは 'インポート'されません2回。 Pythonがモジュールをロードすると、sys.modulesのモジュールがチェックされます。それがそこになければ、そこに入れられ、ロードされます。 (Pythonは参照を持っていない

モジュールは、彼らがfrom camelot import *シナリオにエクスポートされますどのような名前を定義することができ、そして行動が既存の値の名前を作成することで、既存の変数を参照しません:あなたの2つ目の質問に答えるために

)。

多少関連するトピックでは、from camelot import *を実行すると、not the same as a regular importとなります。

+0

ThiefMasterが編集に答えるのに苦しんでいるように見えます。私はこれをここに残しておきます。「〜からのcamelot import *」は通常のインポートと同じではありません。 – Darthfett

関連する問題