ImportError:没有名为包的模块

Posted

技术标签:

【中文标题】ImportError:没有名为包的模块【英文标题】:ImportError: No module named package 【发布时间】:2016-12-11 11:17:26 【问题描述】:

我发现在 Python 中导入模块很复杂,所以我正在做实验来解决它。这是我的文件结构:

PythonTest/
  package/
    __init__.py
    test.py

__init__.py的内容:

package = 'Variable package in __init__.py'
from package import test

test.py的内容:

from package import package
print package

当我离开package(在PythonTest)并执行python package/test.py时,我得到:

Traceback (most recent call last):
  File "package/test.py", line 1, in <module>
    from package import package
ImportError: No module named package

预期的输出是Variable package in __init__.py。我做错了什么?


但是,我可以在交互模式下获得预期的输出:

sunqingyaos-MacBook-Air:PythonTest sunqingyao$ python
Python 2.7.10 (default, Oct 23 2015, 19:19:21) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import package
Package in __init__.py

【问题讨论】:

似乎没有为 package 包设置模块搜索路径。 @user2357112 所以我应该设置PYTHONPATH还是修改sys.path?但是为什么在交互模式下一切正常? 我假设您从与文件相同的目录启动交互模式,因此该路径会自动成为搜索路径的一部分。尝试从一个完全不同的目录启动 python 我调用交互模式的目录正是我执行python package/test.py的目录。当我进入一个完全不同的目录时,这两种方法都不起作用。 python package/test.py 将您正在执行的脚本的目录添加到搜索路径,而不是您启动脚本的目录。 【参考方案1】:

首先让我们看看 Python 如何搜索包和模块。 sys.path

指定模块搜索路径的字符串列表。从环境变量 PYTHONPATH 初始化,加上依赖于安装的默认值。

这就是搜索路径。因此,如果您的模块/包位于sys.path 之一,python 解释器能够找到并导入它。文档说的更多:

在程序启动时初始化,此列表的第一项 path[0] 是包含用于调用 Python 解释器的脚本的目录。如果脚本目录不可用(例如,如果交互调用解释器或从标准输入读取脚本),path[0] 是空字符串,它指示 Python 首先搜索当前目录中的模块。

我修改test.py为例。

import sys; import pprint
pprint.pprint(sys.path)

from package import package
print package 

有两种情况:

$ python package/test.py
['/Users/laike9m/Dev/Python/TestPython/package',
 '/usr/local/lib/python2.7/site-packages/doc2dash-2.1.0.dev0-py2.7.egg',
 '/usr/local/lib/python2.7/site-packages/zope.interface-4.1.3-py2.7-macosx-10.10-x86_64.egg',
 '/usr/local/lib/python2.7/site-packages/six-1.10.0-py2.7.egg',
 '/usr/local/lib/python2.7/site-packages/colorama-0.3.3-py2.7.egg',

如您所见,path[0]/Users/laike9m/Dev/Python/TestPython/package,即包含用于调用 Python 解释器的脚本 test.py 的目录。

$ python                                         
Python 2.7.12 (default, Jun 29 2016, 14:05:02)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import package
['',
 '/usr/local/lib/python2.7/site-packages/doc2dash-2.1.0.dev0-py2.7.egg',
 '/usr/local/lib/python2.7/site-packages/zope.interface-4.1.3-py2.7-macosx-10.10-x86_64.egg',
 '/usr/local/lib/python2.7/site-packages/six-1.10.0-py2.7.egg',
 '/usr/local/lib/python2.7/site-packages/colorama-0.3.3-py2.7.egg',
...

现在是第二种情况,当以交互方式调用时,“path[0] 是空字符串,它指示 Python 首先搜索当前目录中的模块。”当前目录是什么? /Users/laike9m/Dev/Python/TestPython/.(看看这是我机器上的路径,在你的情况下它相当于PythonTest的路径)

现在你知道答案了:

    python package/test.py为什么要给ImportError: No module named package

    因为解释器没有“看到”包。要让解释器知道包packagePythonTest 必须在sys.path 中,但不是。

    为什么这在交互模式下有效?

    因为现在PythonTestsys.path 中,所以解释器能够定位到包package

【讨论】:

以上是关于ImportError:没有名为包的模块的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ImportError:没有名为 lightgbm 的模块

ImportError:没有名为瓶子的模块

ImportError:没有名为 ghostscript 的模块

ImportError:没有名为枚举的模块

ImportError:没有名为 pynotify 的模块。安装模块时

ImportError:没有名为 websocket 的模块