124

Python 的 sys.path 是从哪里初始化的?

UPD:Python 在引用 PYTHONPATH 之前添加了一些路径:

    >>> import sys
    >>> from pprint import pprint as p
    >>> p(sys.path)
    ['',
     'C:\\Python25\\lib\\site-packages\\setuptools-0.6c9-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\orbited-0.7.8-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\morbid-0.8.6.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\demjson-1.4-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stomper-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\uuid-1.30-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stompservice-0.1.0-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\cherrypy-3.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\pyorbited-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\flup-1.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\wsgilog-0.1-py2.5.egg',
     'c:\\testdir',
     'C:\\Windows\\system32\\python25.zip',
     'C:\\Python25\\DLLs',
     'C:\\Python25\\lib',
     'C:\\Python25\\lib\\plat-win',
     'C:\\Python25\\lib\\lib-tk',
     'C:\\Python25',
     'C:\\Python25\\lib\\site-packages',
     'C:\\Python25\\lib\\site-packages\\PIL',
     'C:\\Python25\\lib\\site-packages\\win32',
     'C:\\Python25\\lib\\site-packages\\win32\\lib',
     'C:\\Python25\\lib\\site-packages\\Pythonwin']

我的 PythonPATH 是:

    PYTHONPATH=c:\testdir

我想知道 PYTHONPATH 之前的那些路径来自哪里?

4

2 回答 2

104

Python 真的很努力地智能设置sys.path. 如何设置会变得非常 复杂。以下指南是一个淡化的、有些不完整、有些错误但希望对普通 Python 程序员有用的指南,说明当 Python 确定将什么用作 、 、 和 的初始 值时发生什么在正常的 python安装上。sys.pathsys.executablesys.exec_prefixsys.prefix

首先,python 尽其所能根据操作系统告诉它的信息来确定它在文件系统上的实际物理位置。如果操作系统只是说“python”正在运行,它会发现自己在 $PATH 中。它解析任何符号链接。完成此操作后,它找到的可执行文件的路径将用作 的值sys.executable,没有 ifs、ands 或 buts。

sys.exec_prefix接下来,它确定和 的初始值sys.prefix

如果pyvenv.cfg在同一目录 sys.executable或上一个目录中有一个文件被调用,python 会查看它。不同的操作系统对这个文件做不同的事情。

python 在此配置文件中查找的值之一是配置选项home = <DIRECTORY>。Python 将使用这个目录而不是包含sys.executable 当它动态设置的初始值时的目录sys.prefix。如果applocal = true设置出现在 pyvenv.cfgWindows 上的文件中,但未出现在home = <DIRECTORY>设置中,sys.prefix则将设置为包含sys.executable.

接下来,PYTHONHOME检查环境变量。在 Linux 和 Mac 上, 并sys.prefix设置sys.exec_prefix为环境PYTHONHOME变量(如果存在),取代. 在 Windows 上,如果存在,则设置为环境变量,除非在存在设置,否则将使用该设置。home = <DIRECTORY>pyvenv.cfgsys.prefixsys.exec_prefixPYTHONHOMEhome = <DIRECTORY>pyvenv.cfg

否则,这些sys.prefixsys.exec_prefix通过从 的位置sys.executable或由home给定的目录(pyvenv.cfg如果有)向后走来找到。

如果lib/python<version>/dyn-load在该目录或其任何父目录中找到该文件,则该目录设置为 sys.exec_prefix在 Linux 或 Mac 上。如果 lib/python<version>/os.py在目录或其任何子目录中找到该文件,则该目录将设置为sys.prefixLinux、Mac 和 Windows 上的目录,并sys.exec_prefix设置为与 Windows 上相同的值 sys.prefixapplocal = true如果已设置,则在 Windows 上跳过这整个步骤 。要么使用 的目录,要么sys.executable如果home在 中设置,则将pyvenv.cfg其用于 的初始值sys.prefix

如果它找不到这些“地标”文件或sys.prefix尚未找到,则 python 设置sys.prefix为“后备”值。例如,Linux 和 Mac 使用预编译的默认值作为 和 的sys.prefixsys.exec_prefix。Windows 等到sys.path完全确定为 sys.prefix.

然后,(你们都在等待什么,)python 确定要包含在sys.path.

  1. python 正在执行的脚本目录添加到sys.path. 在 Windows 上,这始终是空字符串,它告诉 python 使用脚本所在的完整路径。
  2. PYTHONPATH 环境变量的内容(如果已设置)将添加到sys.path除非您在 Windows 上并且applocalpyvenv.cfg.
  3. <prefix>/lib/python35.zipLinux/Mac 和 Windows 上 的 zip 文件路径os.path.join(os.dirname(sys.executable), "python.zip")添加到sys.path.
  4. 如果在 Windows 上并且没有applocal = true在 中设置pyvenv.cfg,则添加注册表项的子项的内容( HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\如果有)。
  5. 如果在 Windows 上没有applocal = true设置pyvenv.cfg,并且sys.prefix找不到,则添加注册表项的核心内容HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\(如果存在);
  6. 如果在 Windows 上并且没有applocal = true在 中设置pyvenv.cfg,则添加注册表项的子项的内容( HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\如果有)。
  7. 如果在 Windows 上没有applocal = true设置pyvenv.cfg,并且sys.prefix找不到,则添加注册表项的核心内容HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\(如果存在);
  8. 如果在 Windows 上,并且未设置 PYTHONPATH,未找到前缀,并且不存在注册表项,则添加 PYTHONPATH 的相对编译时值;否则,忽略此步骤。
  9. 编译时宏 PYTHONPATH 中的路径是相对于动态找到的sys.prefix.
  10. 在 Mac 和 Linux 上,sys.exec_prefix添加 的值。在 Windows 上,添加了用于(或将被用于)动态搜索的目录sys.prefix

在 Windows 上的这个阶段,如果没有找到前缀,那么 python 将尝试通过在所有目录中搜索sys.path地标文件来确定它,就像它尝试使用sys.executable之前的目录一样,直到找到一些东西。如果没有,sys.prefix则留空。

最后,在这一切之后,Python 加载了site模块,它进一步添加了以下内容sys.path

它首先从头部和尾部构建最多四个目录。对于头部,它使用sys.prefixand sys.exec_prefix; 空头被跳过。对于尾部,它使用空字符串然后lib/site-packages(在 Windows 上)或lib/pythonX.Y/site-packages 然后lib/site-python(在 Unix 和 Macintosh 上)。对于每个不同的头尾组合,它会查看它是否引用了现有目录,如果是,则将其添加到 sys.path 并检查新添加的配置文件路径。

于 2016-07-15T19:19:54.580 回答
52

“从环境变量 PYTHONPATH 初始化,加上依赖于安装的默认值”

-- http://docs.python.org/library/sys.html#sys.path

于 2009-05-22T13:21:25.457 回答