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

问题: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之前的那些路径来自哪里?

Where is Python’s sys.path initialized from?

UPD: Python is adding some paths before refering to 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']

My PYTHONPATH is:

    PYTHONPATH=c:\testdir

I wonder where those paths before PYTHONPATH’s ones come from?


回答 0

“从环境变量PYTHONPATH初始化,加上与安装有关的默认值”

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

“Initialized from the environment variable PYTHONPATH, plus an installation-dependent default”

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


回答 1

Python确实努力进行智能设置sys.path。如何设置可能会变得非常 复杂。下面的指南是一个打了折扣的,有点不完全,有些-错,但希望-有用的时候Python会什么的使用会发生什么的职级和文件Python程序员指南初始值sys.pathsys.executablesys.exec_prefix,和sys.prefix正常的 python安装上。

首先,python会尽最大努力根据操作系统告诉它在文件系统上的实际物理位置。如果操作系统只是说“ python”正在运行,它将在$ PATH中找到自己。它解析任何符号链接。完成此操作后,它将找到的可执行文件的路径用作sys.executable,no ifs,ands或buts的值。

接下来,确定用于初始值sys.exec_prefixsys.prefix

如果pyvenv.cfg在与该目录相同的目录中有一个文件, sys.executable或者在一个目录中,则python会查看该文件。不同的操作系统对此文件执行不同的操作。

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

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

否则,可以通过从或指定的目录(如果有)的位置向后走来找到sys.prefix和。sys.exec_prefixsys.executablehomepyvenv.cfg

如果lib/python<version>/dyn-load在该目录或其任何父目录中找到该文件,则将该目录设置为 sys.exec_prefix在Linux或Mac上。如果lib/python<version>/os.py在目录或其任何子目录中找到该文件 ,则将该目录设置为sys.prefix在Linux,Mac和Windows上,并sys.exec_prefix设置为与Windows 相同的值 sys.prefix。如果applocal = 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. 除非您在Windows上并且在中设置为true sys.path否则将添加PYTHONPATH环境变量的内容(如果applocal已设置)pyvenv.cfg
  3. <prefix>/lib/python35.zipLinux / Mac和os.path.join(os.dirname(sys.executable), "python.zip")Windows 上 的zip文件路径已添加到中sys.path
  4. 如果在Windows上没有applocal = true在中设置No pyvenv.cfg,则HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\添加注册表项的子项的内容( 如果有)。
  5. 如果在Windows上未applocal = true在中设置No pyvenv.cfg,并且sys.prefix找不到,则添加注册表项的核心内容HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\如果存在);
  6. 如果在Windows上没有applocal = true在中设置No pyvenv.cfg,则HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\添加注册表项的子项的内容( 如果有)。
  7. 如果在Windows上未applocal = true在中设置No pyvenv.cfg,并且sys.prefix找不到,则添加注册表项的核心内容HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\如果存在);
  8. 如果在Windows上并且未设置PYTHONPATH,则找不到前缀,并且不存在注册表项,则添加PYTHONPATH的相对编译时值;否则,将忽略此步骤。
  9. 相对于dynamic-found添加了编译时宏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.prefixsys.exec_prefix; 空头被跳过。对于尾部,它使用空字符串,然后lib/site-packages(在Windows上)或lib/pythonX.Y/site-packages (然后lib/site-python在Unix和Macintosh上)使用。对于每个不同的首尾组合,它会查看它是否指向现有目录,如果是,则将其添加到sys.path中,并检查新添加的配置文件路径。

Python really tries hard to intelligently set sys.path. How it is set can get really complicated. The following guide is a watered-down, somewhat-incomplete, somewhat-wrong, but hopefully-useful guide for the rank-and-file python programmer of what happens when python figures out what to use as the initial values of sys.path, sys.executable, sys.exec_prefix, and sys.prefix on a normal python installation.

First, python does its level best to figure out its actual physical location on the filesystem based on what the operating system tells it. If the OS just says “python” is running, it finds itself in $PATH. It resolves any symbolic links. Once it has done this, the path of the executable that it finds is used as the value for sys.executable, no ifs, ands, or buts.

Next, it determines the initial values for sys.exec_prefix and sys.prefix.

If there is a file called pyvenv.cfg in the same directory as sys.executable or one directory up, python looks at it. Different OSes do different things with this file.

One of the values in this config file that python looks for is the configuration option home = <DIRECTORY>. Python will use this directory instead of the directory containing sys.executable when it dynamically sets the initial value of sys.prefix later. If the applocal = true setting appears in the pyvenv.cfg file on Windows, but not the home = <DIRECTORY> setting, then sys.prefix will be set to the directory containing sys.executable.

Next, the PYTHONHOME environment variable is examined. On Linux and Mac, sys.prefix and sys.exec_prefix are set to the PYTHONHOME environment variable, if it exists, superseding any home = <DIRECTORY> setting in pyvenv.cfg. On Windows, sys.prefix and sys.exec_prefix is set to the PYTHONHOME environment variable, if it exists, unless a home = <DIRECTORY> setting is present in pyvenv.cfg, which is used instead.

Otherwise, these sys.prefix and sys.exec_prefix are found by walking backwards from the location of sys.executable, or the home directory given by pyvenv.cfg if any.

If the file lib/python<version>/dyn-load is found in that directory or any of its parent directories, that directory is set to be to be sys.exec_prefix on Linux or Mac. If the file lib/python<version>/os.py is is found in the directory or any of its subdirectories, that directory is set to be sys.prefix on Linux, Mac, and Windows, with sys.exec_prefix set to the same value as sys.prefix on Windows. This entire step is skipped on Windows if applocal = true is set. Either the directory of sys.executable is used or, if home is set in pyvenv.cfg, that is used instead for the initial value of sys.prefix.

If it can’t find these “landmark” files or sys.prefix hasn’t been found yet, then python sets sys.prefix to a “fallback” value. Linux and Mac, for example, use pre-compiled defaults as the values of sys.prefix and sys.exec_prefix. Windows waits until sys.path is fully figured out to set a fallback value for sys.prefix.

Then, (what you’ve all been waiting for,) python determines the initial values that are to be contained in sys.path.

  1. The directory of the script which python is executing is added to sys.path. On Windows, this is always the empty string, which tells python to use the full path where the script is located instead.
  2. The contents of PYTHONPATH environment variable, if set, is added to sys.path, unless you’re on Windows and applocal is set to true in pyvenv.cfg.
  3. The zip file path, which is <prefix>/lib/python35.zip on Linux/Mac and os.path.join(os.dirname(sys.executable), "python.zip") on Windows, is added to sys.path.
  4. If on Windows and no applocal = true was set in pyvenv.cfg, then the contents of the subkeys of the registry key HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\ are added, if any.
  5. If on Windows and no applocal = true was set in pyvenv.cfg, and sys.prefix could not be found, then the core contents of the of the registry key HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\ is added, if it exists;
  6. If on Windows and no applocal = true was set in pyvenv.cfg, then the contents of the subkeys of the registry key HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\ are added, if any.
  7. If on Windows and no applocal = true was set in pyvenv.cfg, and sys.prefix could not be found, then the core contents of the of the registry key HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\ is added, if it exists;
  8. If on Windows, and PYTHONPATH was not set, the prefix was not found, and no registry keys were present, then the relative compile-time value of PYTHONPATH is added; otherwise, this step is ignored.
  9. Paths in the compile-time macro PYTHONPATH are added relative to the dynamically-found sys.prefix.
  10. On Mac and Linux, the value of sys.exec_prefix is added. On Windows, the directory which was used (or would have been used) to search dynamically for sys.prefix is added.

At this stage on Windows, if no prefix was found, then python will try to determine it by searching all the directories in sys.path for the landmark files, as it tried to do with the directory of sys.executable previously, until it finds something. If it doesn’t, sys.prefix is left blank.

Finally, after all this, Python loads the site module, which adds stuff yet further to sys.path:

It starts by constructing up to four directories from a head and a tail part. For the head part, it uses sys.prefix and sys.exec_prefix; empty heads are skipped. For the tail part, it uses the empty string and then lib/site-packages (on Windows) or lib/pythonX.Y/site-packages and then lib/site-python (on Unix and Macintosh). For each of the distinct head-tail combinations, it sees if it refers to an existing directory, and if so, adds it to sys.path and also inspects the newly added path for configuration files.