当import某个模块时,Python会使用sys.path中指定目录,按顺序搜索导入的模块。如果没有找到,则汇报模块找不到错误。后面会介绍控制搜索目录,即sys.path变量的选项与方法。
权威参考文档是 PEP370:https://www.python.org/dev/peps/pep-0370/
主要是为用户提供一种机制,可以在自己的账户目录中安装自己专用的本地Python包。
在Unix上,用户站点目录位于$HOME/.local/lib/python<version>/site-packages/中,Windows上也定义了相应的目录,参看下例:
Unix (including Mac OS X)
~/.local/lib/python2.6/site-packages
Windows
%APPDATA%/Python/Python26/site-packages
在安装包时,使用pip install --user选项。
第三方站点目录位于$PATHHOME/lib/python<version>/site-packages/,默认情况下,通过pip命令(不指定pip install --user选项)安装的第三方包,都会安装在第三方站点目录中。
当向第三方站点目录安装包时,如果该包已经存在于用户站点目录中,pip则会通知你,你的想法已经被满足了。我怀疑反之亦然,但是没做实验。
由此可见,不会有同名的包,既位于用于站点目录也位于第三方站点目录中。所以不用担心这两个站点目录的搜索顺序。
参看下例:
site.py位于$PYTHONHOME/lib/python3.7/目录下。这个文件负责将第三方包里的模块的搜索路径添加到sys.path变量中。单独执行这个脚本时,可以打印出一些有用的信息(参考下面的例子)。
Python有一些选项可以控制Python启动时,如何设置模块搜索变量sys.path。
-E: 忽略PYTHON*环境变量(例如PYTHONPATH)
-s(小写):不添加用户站点目录(user site directory)到sys.path中,等价于PYTHONNOUSERSITE
-S(大写):Python启动时,不执行import site,即不添加用户站点目录与第三方站点目录到sys.path中;看起来-S暗含着-s选项,反之不然。
Python在启动时,
- 如果没有指定-E选项,则默认会把PYTHONPATH环境变量中指定的所有目录(不检查目录是否存在)都添加到sys.path变量中,而且放置在站点目录之前;
- 如果使用-E选项,则PYTHONPATH环境变量会被忽略。
在站点目录下,包括用户站点目录与第三方站点目录,例如/home/tony/python37/lib/python3.7/site-packages或者/home/tony/.local/lib/python3.7/site-packages,可以创建一些后缀为.pth的文本文件,例如foo.pth与bar.pth,用于配置Python的模块查找路径。
这些文件具有如下的格式,注意文件中的目录是相对路径,同时假设site-packages目录下有foo目录与bar目录,但是bletch目录并不存在:
# foo package configuration
foo
bar
bletch
# bar package configuration
bar
在Python启动时,如果导入了站点目录,即没有使用(-S或-s选项),则site.py脚本会列举所有的*.pth文件,将其中的目录附加到sys.path的结尾处,添加规则如下:
- 新加入的目录按照目录名大小写敏感顺序排序,例如bar在foo之前。
- 配置文件中定义的目录但是文件系统中不存在的目录,不会被添加到sys.path中