ImportError: No module named package

ImportError: No module named package

我发现在 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

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

A list of strings that specifies the search path for modules. Initialized from the environment variable PYTHONPATH, plus an installation-dependent default.

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

As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first.

我修改了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的路径)

现在你知道答案了:

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

    因为解释器没有"see"包。要让解释器知道包 packagePythonTest 必须在 sys.path 中,但事实并非如此。

  2. 为什么这个在交互模式下工作?

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