Python での循環インポートの処理方法に困惑しています。私は最小限の質問を抽出しようとしましたが、この正確なバリアントが以前に尋ねられたとは思いません. 基本的に、私は違いを見ています
import lib.foo
と
import lib.foo as f
lib.foo
と の間に循環依存関係がある場合lib.bar
。どちらも同じように動作することを期待していました。(おそらく半分初期化された) モジュールはsys.modules
、ローカル名前空間で検出され、配置されます。import lib.foo
(テストから、これが実際にローカル名前空間に配置されていることに気付きlib
ました — オーケー、lib.foo.something
とにかくその構文を使用します。)
ただし、lib.foo
がすでに にあるsys.modules
場合は、 の属性としてimport lib.foo as f
アクセスしようとし、AttributeError を発生させます。動作が (一見) の存在に依存するのはなぜですか?foo
lib
sys.modules
また、この動作はどこに文書化されていますか? Pythonimport
ステートメント リファレンスがこの動作を説明しているとは思わないか、少なくとも抽出できませんでした :-)
全体として、モジュール内のシンボルではなく、モジュールをインポートする推奨されるスタイルを使用するようにコードベースを変更しようとしています。
from project.package import moduleA
from project.package import moduleB
しかし、2 つのモジュール間に循環インポートがあると失敗します。2 つのモジュールの最上位の定義が相互に依存しない限り (たとえば、 にmoduleB
基本クラスを持つサブクラスがない場合moduleA
)、それが機能することを期待していました。
テスト スクリプト:
#!/bin/sh
rm -r lib; mkdir lib
touch lib/__init__.py
cat > lib/foo.py <<EOF
# lib.foo module
print '{ foo'
#import lib.bar # works
import lib.bar as b # also works
#from lib import bar # also works
print 'foo }'
EOF
cat > lib/bar.py <<EOF
# lib.bar module
print '{ bar'
#import lib.foo # works
import lib.foo as f # AttributeError: 'module' object has no attribute 'foo'
#from lib import foo # ImportError: cannot import name foo
print 'bar }'
EOF
python -c 'import lib.foo'