1

两个新安装的具有相同 python36 版本的相同暂存 VM 的 sys.path 值不同:

第一个虚拟机

[root@vm1 ~]# python36 -m site
sys.path = [
    '/root',
    '/usr/lib64/python36.zip',
    '/usr/lib64/python3.6',
    '/usr/lib64/python3.6/lib-dynload',
    '/usr/lib64/python3.6/site-packages',
    '/usr/lib/python3.6/site-packages',
]
USER_BASE: '/root/.local' (doesn't exist)
USER_SITE: '/root/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

第二台虚拟机

[root@vm2 ~]# python36 -m site
sys.path = [
    '/root',
    '/usr/lib64/python36.zip',
    '/usr/lib64/python3.6',
    '/usr/lib64/python3.6/lib-dynload',
    '/usr/local/lib64/python3.6/site-packages',
    '/usr/local/lib/python3.6/site-packages',
    '/usr/lib64/python3.6/site-packages',
    '/usr/lib/python3.6/site-packages',
]
USER_BASE: '/root/.local' (doesn't exist)
USER_SITE: '/root/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

由于某些原因,第二个 VM 具有 /usr/local/lib* 路径。

两台机器上的 os.environ 显示相同的变量值:

  • PYTHONPATH 没有自定义路径值
  • 原始 PATH 变量(不知道是否连接到 PYTHONPATH)也相同

    [root@vm1 ~] 环境 | grep -E "^PATH=" PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/java/latest/bin:/opt/java/latest/ jre/bin:/root/bin

当操作系统端没有为 PYTHONPATH 配置自定义值时,python36 如何在初始安装期间初始化 PYTHONPATH(sys.path)?

4

1 回答 1

2

正常安装预计能够在没有任何PYTHONPATH环境变量的情况下运行。正如文档中所解释的那样,PYTHONPATH用户是否可以……</p>

增加模块文件的默认搜索路径。格式与shell 的PATH 相同:一个或多个由os.pathsep 分隔的目录路径名(例如Unix 上的冒号或Windows 上的分号)。不存在的目录会被静默忽略。

因此,标准的 Python 安装程序(包括在本地构建和运行make install,以及在 python.org 的下载中提供的 Windows 和 macOS 二进制安装程序)都没有做任何事情来创建PYTHONPATH值或在您的环境中设置它。并且大多数半官方和第三方软件包(如 Python 包含或由 Linux 发行版和 Apple 打包,Downloads/Other 下的不太常见的平台安装程序,“电池加”Python 发行版如 Anaconda 等)都可以工作一样的方法。


请注意,PYTHONPATH目录已添加到默认搜索路径。如同一文档中所述:

默认搜索路径取决于安装,但通常以 prefix/lib/pythonversion 开头(参见上面的 PYTHONHOME)。它始终附加到 PYTHONPATH。

如上文接口选项中所述,将在 PYTHONPATH 前面的搜索路径中插入一个附加目录。搜索路径可以在 Python 程序中作为变量 sys.path 进行操作。

这也在sys.path

指定模块搜索路径的字符串列表。从环境变量 PYTHONPATH 初始化,加上依赖于安装的默认值。

在程序启动时初始化时,此列表的第一项 path[0] 是包含用于调用 Python 解释器的脚本的目录。如果脚本目录不可用(例如,如果交互调用解释器或从标准输入读取脚本),path[0] 是空字符串,它指示 Python 首先搜索当前目录中的模块。请注意,脚本目录是在 PYTHONPATH 插入的条目之前插入的。

…</p>

另见模块site这描述了如何使用 .pth 文件来扩展 sys.path。

与 不同的是PYTHONPATH,这种site机制有时会被第三方和半官方安装使用。例如,Apple 使用它将其Extras预安装包库添加pyobjc到 macOS 上的内置 Python 2.7 中。


如果您想知道sysCPython 中的模块如何加载“依赖于安装的默认值”,它最终归结为一个公共 C API 函数Py_GetPath

返回默认模块搜索路径;这是根据程序名称(由上面的 Py_SetProgramName() 设置)和一些环境变量计算得出的。返回的字符串由一系列由平台相关分隔符分隔的目录名称组成。分隔符是 ':' 在 Unix 和 Mac OS X 上,';' 在 Windows 上。返回的字符串指向静态存储;调用者不应修改其值。该列表sys.path在解释器启动时使用此值初始化;它可以(并且通常)稍后修改以更改加载模块的搜索路径。

如果你想看看 C 代码是如何工作的,你可能想从 开始_PyPathConfig_Init,因为实际Py_GetPath只是调用一个函数来确保它已被调用,然后将值从它设置的结构中提取出来。

于 2018-06-25T22:39:09.757 回答