我对 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
尝试foo
作为属性访问lib
并引发 AttributeError。为什么行为(看似)取决于 中的存在sys.modules
?
此外,这种行为记录在哪里?我不觉得Pythonimport
语句参考解释了这种行为,或者至少我无法提取它:-)
总而言之,我正在尝试更改代码库以使用导入模块时经常推荐的样式,而不是模块中的符号:
from project.package import moduleA
from project.package import moduleB
但是当两个模块之间存在循环导入时,这会失败。只要两个模块中的顶级定义不相互依赖(例如,在 中没有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'