首先,让我们看看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
,这是包含脚本test.py
的目录,该脚本被用于调用Python解释器。
$ 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
?
因为解释器没有"看到"该包。为了使解释器能够意识到包package
,必须将PythonTest
添加到sys.path
中,但实际上它没有被添加。
为什么交互模式下可以工作?
因为现在PythonTest
被添加到了sys.path
中,所以解释器可以找到包package
。
PYTHONPATH
还是修改sys.path
呢?但为什么在交互模式下一切都正常呢? - nalzokpython package/test.py
的目录。当我进入一个完全不同的目录时,这两种方法都不起作用。 - nalzokpython package/test.py
会将执行脚本的目录添加到搜索路径中,而不是启动脚本的目录。 - user2357112PythonTest
中编写另一个模块,并从中调用test.py
吗?(也许直接调用包中的模块而不经过其包是一个错误?) - nalzok