Python では、2 つのモジュールがimport
相互に試行すると何が起こりますか? より一般的には、複数のモジュールがimport
循環的に試行すると何が起こりますか?
参照「ImportError: 名前 X をインポートできません」または「AttributeError: ... (おそらく循環インポートが原因)」についてはどうすればいいですか?起こり得る一般的な問題と、そのようなインポートを回避するためにコードを書き直す方法に関するアドバイスについては、循環インポートはコールスタックの上のほうでは機能しているように見えるのに、下のほうでは ImportError を発生させるのはなぜでしょうか?問題が発生する理由と仕組みに関する技術的な詳細については、
ベストアンサー1
import foo
(inside bar.py
) とimport bar
(inside )を実行するとfoo.py
、正常に動作します。実際に何かが実行される頃には、両方のモジュールが完全にロードされ、相互に参照されるようになります。
問題は、代わりにfrom foo import abc
(inside bar.py
) とfrom bar import xyz
(inside foo.py
) を実行する場合です。なぜなら、各モジュールをインポートする前に、他のモジュールが既にインポートされている (つまり、インポートする名前が存在する) 必要があるためです。
Python 2 と Python 3 での循環インポートの動作例
記事Python の循環インポートが致命的となるのはどのような場合ですか?循環インポートが、上で説明した理由により致命的ではない場合の例を 4 つ示します。
モジュールの先頭; from なし; Python 2 のみ
# lib/foo.py # lib/bar.py
import bar import foo
def abc(): def xyz():
print(bar.xyz.__name__) print(foo.abc.__name__)
モジュールの先頭; from ok; relative ok; Python 3 のみ
# lib/foo.py # lib/bar.py
from . import bar from . import foo
def abc(): def xyz():
print(bar.xyz.__name__) print(abc.__name__)
モジュールの先頭。from なし。相対なし
# lib/foo.py # lib/bar.py
import lib.bar import lib.foo
def abc(): def xyz():
print(lib.bar.xyz.__name__) print(lib.foo.abc.__name__)
モジュールの下部; モジュールではなく属性をインポート; 正常から
# lib/foo.py # lib/bar.py
def abc(): def xyz():
print(xyz.__name__) print(abc.__name__)
from .bar import xyz from .foo import abc
関数の先頭; OKから
# lib/foo.py # lib/bar.py
def abc(): def xyz():
from . import bar from . import foo
print(bar.xyz.__name__) print(foo.abc.__name__)
追加の例
上記の記事では、スターの輸入については説明されていません。