モジュールは相互に周期的にインポートできますが、落とし穴があります。単純なケースでは、import
ステートメントをファイルの最後に移動するか、from
構文を使用しないことで機能するはずです。
これが機能する理由は次のとおりです。
モジュールをインポートすると、Python は最初に をチェックしますsys.modules
。そこにある場合は、そこからインポートするだけです。そこにない場合は、通常の方法でインポートしようとします。基本的に、ファイルを見つけてその中のものを実行します。
モジュールを実行すると、モジュールの内容が読み込まれます。たとえば、次のような創造的な名前のモジュールがあるとしますexample_opener
。
import webbrowser
def open_example():
webbrowser.open('http://www.example.com/')
最初は、モジュールは空です。次に、Python が実行されます。
import webbrowser
その後、モジュールには のみが含まれますwebbrowser
。次に、Python はこれを実行します。
def open_example():
webbrowser.open('http://www.example.com/')
Python は を作成しますopen_example
。モジュールにwebbrowser
とが含まれるようになりopen_example
ました。
次のwebbrowser
コードが含まれているとします。
from example_opener import open_example
def open(url):
print url
Sayexample_opener
が最初にインポートされます。このコードが実行されます:
import webbrowser
webbrowser
はまだインポートされていないため、Python は次の内容を実行しますwebbrowser
。
from example_opener import open_example
example_opener
インポートされましたが、まだ完全には実行されていません。Python は気にしません。Python は からモジュールを引き出しますsys.modules
。この時点で、example_opener
はまだ空です。まだ定義されておらopen_example
ず、インポートも完了していませんwebbrowser
。Python は で見つからないためopen_example
、example_opener
失敗します。
open_example
の末尾webbrowser
との末尾webbrowser
からインポートした場合はどうなるexample_opener
でしょうか。Python は、次のコードを実行して開始します。
def open_example():
webbrowser.open('http://www.example.com/')
webbrowser
はまだ存在しませんが、open_example
呼び出されるまでは関係ありません。example_opener
のみが含まれるようになりましopen_example
た。次に実行します。
import webbrowser
まだインポートされていないため、Python が実行されwebbrowser
ます。始まるよ:
def open(url):
print url
を定義しますopen
。次に実行します。
from example_opener import open_example
example_opener
にあるsys.modules
ので、それを使用します。example_opener
が含まれopen_example
ているため、成功します。Python はインポートを終了しwebbrowser
ます。webbrowser
からのインポートはこれで終了example_opener
です。の最後の処理なexample_opener
ので、 のインポートもexample_opener
成功しました。