我不明白为什么Python在这种情况下引发异常。我尝试从全局安装的包导入,同时存在与包名称具有相同前缀的文件。我错过了什么?意外的导入错误
$ touch fabric.py
$ python2
...
>>> from fabric.api import run
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named api
我不明白为什么Python在这种情况下引发异常。我尝试从全局安装的包导入,同时存在与包名称具有相同前缀的文件。我错过了什么?意外的导入错误
$ touch fabric.py
$ python2
...
>>> from fabric.api import run
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named api
从Python文档:
该名称将在导入搜索的各个阶段中使用,并且它可能是一个子模块,例如虚线路径foo.bar.baz。在这种情况下,Python首先尝试导入foo,然后foo.bar,最后导入foo.bar.baz。如果任何中间导入失败,则会引发ModuleNotFoundError。
所以,import fabric.api
尝试加载fabric.py
第一和成功,因为它找到你fabric.py
文件。接下来,它会尝试加载api
它刚加载的内容,但不起作用。
所以你的fabric.py
是阴影fabric
全球包。
Python有位置的路径来寻找模块:sys.path
['', ..., '/usr/lib/python2.7/site-packages/rsa-3.1.1-py2.7.egg', ...,
'/usr/lib/python2.7/site-packages', ...]
它搜索从左至右匹配模块。
所以它首先找到本地模块。 这没有任何属性api
。
如果导入本地模块并将site-packages子模块作为其子模块导入,则不明显。
所以'module.submodule'可以是一个具有属性或包的模块? – planetp
它不是“import fabric”,它的“import fabric.api”暗示层次结构 – planetp
@planetp我编辑了我的答案,并试图使它更完整:) – Guillaume
我想我开始明白了。最难的部分是忘记我的Perl背景:) – planetp