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

发布于 2024-07-22 08:35:49 字数 1523 浏览 4 评论 0原文

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兔小萌 2024-07-29 08:35:49

编辑

当我在 2015 年写这篇文章时,没有关于这个主题的文档。 现在有 根据评论,如果您也想查看一下。 中还有该算法的散文解释代码库中 getpath.py 的注释。 我仍然相信我的答案是相关的并且相对当前。

原文如下

Python 确实努力智能地设置 sys.path< /代码>。 怎么样
set 可以得到 真的 复杂。 以下指南是淡化的,
有点不完整,有点错误,但希望有用的指南
对于普通的Python程序员来说,当Python发生时会发生什么
找出用作 sys.path初始值
正常情况下的 sys.executablesys.exec_prefixsys.prefix
蟒蛇安装。

首先,Python尽最大努力弄清楚它的实际物理量
根据操作系统的指示在文件系统上的位置
它。 如果操作系统只是说“python”正在运行,它会发现自己位于 $PATH 中。
它解析任何符号链接。 一旦完成此操作,路径
它找到的可执行文件用作 sys.executable 的值,没有 ifs,
和,或但是。

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

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

python 在此配置文件中查找的值之一是
配置选项home =。 Python 将使用此目录而不是包含 sys.executable 的目录
当它稍后动态设置 sys.prefix 的初始值时。 如果 applocal = true 设置出现在
Windows 上的 pyvenv.cfg 文件,但不是 home = 设置,
那么sys.prefix将被设置为包含sys.executable的目录。

接下来,检查 PYTHONHOME 环境变量。 在 Linux 和 Mac 上,
sys.prefixsys.exec_prefix 设置为 PYTHONHOME 环境变量,如果
它存在,取代pyvenv.cfg中的任何home =设置。 在 Windows 上,
sys.prefixsys.exec_prefix 设置为 PYTHONHOME 环境变量,
如果存在,除非pyvenv.cfg中存在home =设置,
而是使用它。

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

如果在该目录中找到文件 lib/python/dyn-load
或其任何父目录,该目录被设置为
Linux 或 Mac 上的 sys.exec_prefix。 如果文件
lib/python/os.py 在目录或其任何目录中找到
子目录,该目录在 Linux 上设置为 sys.prefix,
Mac 和 Windows,将 sys.exec_prefix 设置为与
Windows 上的 sys.prefix。 如果出现以下情况,在 Windows 上将跳过整个步骤:
applocal = true 已设置。 sys.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 中,除非
    在 Windows 上,applocalpyvenv.cfg 中设置为 true。
  3. zip 文件路径,在 Linux/Mac 上为 /lib/python35.zip
    Windows 上的 os.path.join(os.dirname(sys.executable), "python.zip") 添加到 sys.path 中。
  4. 如果在 Windows 上并且在 pyvenv.cfg 中未设置 applocal = true,则注册表项的子项的内容
    添加 HK_CURRENT_USER\Software\Python\PythonCore\\PythonPath\(如果有)。
  5. 如果在Windows上并且在pyvenv.cfg中没有设置applocal = true,并且找不到sys.prefix
    然后添加注册表项 HK_CURRENT_USER\Software\Python\PythonCore\\PythonPath\核心内容(如果存在);
  6. 如果在 Windows 上并且在 pyvenv.cfg 中未设置 applocal = true,则注册表项的子项的内容
    添加 HK_LOCAL_MACHINE\Software\Python\PythonCore\\PythonPath\(如果有)。
  7. 如果在Windows上并且在pyvenv.cfg中没有设置applocal = true,并且找不到sys.prefix
    然后添加注册表项 HK_CURRENT_USER\Software\Python\PythonCore\\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 添加内容:

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


编辑:不再有 getpathp.c< /a> (链接在复杂词的开头)自 2021 年 12 月,因为实现已移植到 Python:<代码>getpath.py

EDIT

When I wrote this back in 2015, there was no documentation on the subject. There is now per the comments, if you wanted to also check that out. There is also a prose explanation of the algorithm in the comments of getpath.py in the code base. I still believe my answer to be relevant and relatively current.

ORIGINAL TEXT FOLLOWS

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.


EDIT: There is no more getpathp.c (link at the beginning on complicated word) since Dec 2021 because implementation was ported to Python: getpath.py

不美如何 2024-07-29 08:35:49

“从环境变量 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文