モジュールは相互に周期的にインポートできますが、落とし穴があります。単純なケースでは、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成功しました。