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

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 之前的那些路径是从哪里来的?

167555 次浏览

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

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

Python 真的很努力地智能地设置 sys.path 可以得到 真的 很复杂, 有些不完整,有些错误,但希望是有用的指南 对于普通的 python 程序员来说,当 python 弄清楚什么是 sys.path初始值, 正常上的 sys.executablesys.exec_prefixsys.prefix Python 安装。

首先,python 尽最大努力找出它的实际物理层 根据操作系统的信息在文件系统上定位 如果操作系统只是说“ python”正在运行,它会发现自己在 $PATH 中。 它解析任何符号链接 它找到的可执行文件被用作 sys.executable的值,没有 if, 还是“但是”。

接下来,它确定 sys.exec_prefixsys.prefix.

如果有一个名为 pyvenv.cfg的文件在与 在 sys.executable或者其中一个目录上,python 查看它 操作系统对该文件执行不同的操作。

Python 在此配置文件中查找的值之一是 配置选项 home = <DIRECTORY>.Python 将使用此目录而不是包含 sys.executable的目录 当它稍后动态设置 sys.prefix的初始值时 在 Windows 上的 pyvenv.cfg文件,但不是 home = <DIRECTORY>设置, 然后将 sys.prefix设置为包含 sys.executable的目录。

接下来,我们来检查一下 PYTHONHOME的环境变量,在 Linux 和 Mac 上, 如果 sys.prefixsys.exec_prefix被设置为 PYTHONHOME环境变量,则 它存在,取代任何 home = <DIRECTORY>设置在 pyvenv.cfg, sys.prefixsys.exec_prefix被设置为 PYTHONHOME环境变量 如果它存在,则 除非中存在 home = <DIRECTORY>设置, 它被用来代替。

否则,这些 sys.prefixsys.exec_prefix是通过向后走发现的 从 sys.executable的位置,或者 pyvenv.cfg给出的 home目录(如果有的话)。

如果在该目录中找到文件 lib/python<version>/dyn-load 或其任何父目录,则该目录设置为 在 Linux 或 Mac 上使用 sys.exec_prefix lib/python<version>/os.py可以在目录中找到,也可以在其 子目录,则该目录在 Linux 上被设置为 sys.prefix, Mac 和 Windows,sys.exec_prefix设置为与 在 Windows 上跳过这整个步骤,如果 设置了 applocal = truesys.executable的目录为 如果在 pyvenv.cfg中设置了 home,则使用 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除非 applocalpyvenv.cfg中设置为 true。
  3. Zip 文件路径,在 Linux/Mac 和 在 Windows 上的 os.path.join(os.dirname(sys.executable), "python.zip"),被添加到 sys.path
  4. 如果在 Windows 上没有在 pyvenv.cfg中设置 applocal = true,那么注册表项的子键的内容 如果有,则添加 HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\
  5. 如果在 Windows 上没有在 pyvenv.cfg中设置 applocal = true,并且找不到 sys.prefix, 然后添加注册表项 HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\核心内容,如果它存在的话;
  6. 如果在 Windows 上没有在 pyvenv.cfg中设置 applocal = true,那么注册表项的子键的内容 如果有,则添加 HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\
  7. 如果在 Windows 上没有在 pyvenv.cfg中设置 applocal = true,并且找不到 sys.prefix, 然后添加注册表项 HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\核心内容,如果它存在的话;
  8. 如果未在 Windows 上设置 PYTHONPATH,则未找到前缀,且不存在注册表项,则 将添加 PYTHONPATH 的相对编译时值; 否则将忽略此步骤。
  9. 编译时宏 PYTHONPATH 中的路径是相对于动态发现的 sys.prefix添加的。
  10. 在 Mac 和 Linux 上,添加 sys.exec_prefix的值 用于动态搜索 sys.prefix的 补充。

在 Windows 的这个阶段,如果没有找到前缀,那么 python 将尝试 通过在 sys.path中的目录中搜索地标文件来确定它, 正如它之前尝试处理 sys.executable目录一样,直到找到某些内容为止。 如果没有,则 sys.prefix为空。

最后,在所有这一切之后,Python 加载 site模块,它将更多的内容添加到 sys.path:

它首先从一个头和一个 尾部。头部采用 sys.prefixsys.exec_prefix; 对于尾部,它使用空字符串 然后是 lib/site-packages(在 Windows 上)或 lib/pythonX.Y/site-packages 然后是 lib/site-python(在 Unix 和 Macintosh 上) 不同的头尾组合,它看看是否指的是一个现有的 目录,如果是的话,将它添加到 sys.path 并检查新的 配置文件的添加路径。