私は、次の行を持つボトルWebサーバーモジュールを持っています。
from foobar.formtools import auto_process_form_insert
そしてその foobar.formtools
モジュールには次の行が含まれます。
from foobar.webserver import redirect, redirect_back
もちろん、どちらも次のエラーになります(それぞれ):
ImportError:名前auto_process_form_insertをインポートできません
ImportError:名前リダイレクトをインポートできません
Python 2つのモジュールは相互にインポートできず、すべてのモジュールのインポートは本質的に階層的である必要がありますか、それとも何か間違っているのですか?これらすべての素敵な関数を新しいモジュールに配置しますか?
モジュールcan相互に周期的にインポートしますが、キャッチがあります。単純な場合、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
_
_example_opener
_が最初にインポートされるとします。次のコードが実行されます:
_import webbrowser
_
webbrowser
はまだインポートされていないため、Pythonはwebbrowser
の内容を実行します。
_from example_opener import open_example
_
_example_opener
_ hasはインポートされましたが、まだ完全には実行されていません。 Pythonは気にしません。 Pythonは、モジュールを_sys.modules
_から引き出します。この時点では、_example_opener
_はまだ空です。 _open_example
_はまだ定義されておらず、webbrowser
のインポートも完了していません。 Pythonは_open_example
_で_example_opener
_を見つけることができないため、失敗します。
webbrowser
の末尾から_open_example
_をインポートし、_example_opener
_の末尾からwebbrowser
をインポートした場合はどうなりますか? 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
_のインポートも完了し、成功します。
しないでくださいfrom ... import ...
。ただimport ...
およびモジュール名を使用してそのオブジェクトを参照します。