72

次の行を含むボトル 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 つのモジュールが相互にインポートできず、すべてのモジュールのインポートは本質的に階層的でなければならないという事実だけですか、それとも何か間違っていますか? あるいは、これらすべての優れた機能を新しいモジュールに配置する以外に回避策はありますか?

4

2 に答える 2

93

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

于 2012-07-28T05:25:48.937 に答える
35

しないでくださいfrom ... import ...import ...モジュール名を使用してオブジェクトを参照するだけです。

于 2012-07-28T05:37:47.800 に答える