使用“从包导入”模块语法时,Python循环导入失败
可能重复:使用“从包导入”模块语法时,Python循环导入失败,python,import,cyclic-reference,Python,Import,Cyclic Reference,可能重复: 考虑以下python中循环导入的示例: main.py: from pkg import foo pkg/\uuuu init.py\uuuu: # empty pkg/foo.py: from pkg import bar 包装/bar.py: from pkg import foo 运行main.py将导致异常: Traceback (most recent call last): File "/path/to/main.py", line 1, in <mo
考虑以下python中循环导入的示例: main.py:
from pkg import foo
pkg/\uuuu init.py\uuuu:
# empty
pkg/foo.py:
from pkg import bar
包装/bar.py:
from pkg import foo
运行main.py将导致异常:
Traceback (most recent call last):
File "/path/to/main.py", line 1, in <module>
from pkg import foo
File "/path/to/pkg/foo.py", line 1, in <module>
from pkg import bar
File "/path/to/pkg/bar.py", line 1, in <module>
from pkg import foo
ImportError: cannot import name foo
这将使这个例子起作用
为什么会发生这种情况?*import package.module“和”from package import module“不应该是等价的吗(后面的额外名称绑定除外)?首先,您必须了解:
变量在import mechanize中起到缓存的作用,这意味着如果我们第一次导入模块,包含该模块名称的条目将添加到sys.modules
,因此当我们下次尝试导入同一模块时,我们将只从sys.modules
,我们将不再执行该模块sys.mod>中获取已缓存的模块ules
和pkg-import-foo中的import-pkg.foo
之间的区别在于,第二个也是等效的:
后跟import-pkg.foo
(查看我的答案了解更多细节)getattr(pkg,'foo')
main.py
:我们首先从pkg import foo执行行,因此首先将条目pkg.foo
添加到sys.modules
(即sys.modules==True
)中,然后尝试导入foo
2-在foo.py
:当导入foo
时,我们最终执行这一行:从pkg导入bar
,然后再次将条目pkg.bar
添加到sys.modules
;然后开始导入bar
,这里需要注意的是,我们仍然在执行foo.py
,所以我们很友好off仍然从pkg import foo执行这一行
3-在bar.py
中:现在导入bar.py
时,我们最终执行行:from pkg import foo
,但是请记住,我们已经在sys.modules
中为pkg.foo
创建了一个条目,这意味着执行foo.py
将被跳过,而导入机械化将获得sys.modules['pkg.foo']
entry,现在我们将执行getattr(pkg,'foo')
,如上所述,但请记住'pkg.foo'没有完成导入;这意味着没有解释错误的属性foo
现在,如果只输入bar.py
import pkg.foo,则不会出现上次导致我们出现问题的行:getattr(pkg,'foo')
HTH,我已经用python 2.7.3进行了测试。python 3.2.3也有同样的表现。可能会对你有所帮助。特别是第二个答案。或者更好的答案。谢谢@Bakariu。链接给出了我问题的确切答案。我已经在评论中链接了你的答案,并将这个问题标记为重复,因为问题实际上是相同的。谢谢@mouad.我不可能要求更好的答案。我的理由是(如果我没有弄错的话)使用
getattr(pkg,'foo')
代替sys.modules['pkg.foo']
,因为当x
是一个模块而y
是模块x
中的一个字段时,同样的语法必须工作。
# from pkg import foo
import pkg.foo