# `site` --- 站点专属的配置钩子

源代码: Lib/site.py

这个模块将在初始化时被自动导入。 此自动导入可以通过使用解释器的 `-S` 选项来屏蔽。

Importing this module normally appends site-specific paths to the module search path and adds callables, including `help()` to the built-in namespace. However, Python startup option `-S` blocks this, and this module can be safely imported with no automatic modifications to the module search path or additions to the builtins. To explicitly trigger the usual site-specific additions, call the `main()` function.

在 3.3 版本发生变更: 在之前即便使用了 `-S`，导入此模块仍然会触发路径操纵。

它会以一个头部和一个尾部来构造至多四个目录作为起点。对于头部，它将使用 `sys.prefix` 和 `sys.exec_prefix`；空的头部会被跳过。对于尾部，它将使用空字符串然后是 `lib/site-packages` (在 Windows 上) 或 `lib/pythonX.Y[t]/site-packages` (在 Unix 和 macOS 上)。 (可选后缀 "t" 表示 free-threaded build，并会在 `"t"` 存在于 `sys.abiflags` 常量中时被添加。) 对于每个不同的头部 - 尾部组合，它会查看其是否指向现有的目录，如果确实如此，则将其添加到 `sys.path` 并且还会检查新添加目录中的配置文件。

在 3.5 版本发生变更: 对 "site-python" 目录的支持已被移除。

在 3.13 版本发生变更: 在 Unix 上，自由线程 Python 安装版是在版本专属的目录名称中以 "t" 后缀来标识的，例如 `lib/python3.13t/`。

在 3.14 版本发生变更: `site` is no longer responsible for updating `sys.prefix` and `sys.exec_prefix` on 虚拟环境. This is now done during the path initialization. As a result, under 虚拟环境, `sys.prefix` and `sys.exec_prefix` no longer depend on the `site` initialization, and are therefore unaffected by `-S`.

When running under a virtual environment, the `pyvenv.cfg` file in `sys.prefix` is checked for site-specific configurations. If the `include-system-site-packages` key exists and is set to `true` (case-insensitive), the system-level prefixes will be searched for site-packages, otherwise they won't. If the system-level prefixes are not searched then the user site prefixes are also implicitly not searched for site-packages.

The `site` module recognizes two startup configuration files of the form `name.pth` for path configurations, and `name.start` for pre-first-line code execution. Both files can exist in one of the four directories mentioned above. Within each directory, these files are sorted alphabetically by filename, then parsed in sorted order.

## Path extensions (`.pth` files)

`name.pth` contains additional items (one per line) to be appended to `sys.path`. Items that name non-existing directories are never added to `sys.path`, and no check is made that the item refers to a directory rather than a file. No item is added to `sys.path` more than once. Blank lines and lines beginning with `#` are skipped.

For backward compatibility, lines starting with `import` (followed by space or tab) are executed with `exec()`.

在 3.13 版本发生变更: 现在 `.pth` 文件会首先使用 UTF-8 来解码，如果失败会再改用 locale encoding 来解码。

在 3.15 版本发生变更: `.pth` file lines starting with `import` are deprecated. During the deprecation period, such lines are still executed (except in the case below), but a diagnostic message is emitted only when the `-v` flag is given.

`import` lines in `name.pth` are silently ignored when a matching `name.start` file exists.

Errors on individual lines no longer abort processing of the rest of the file. Each error is reported and the remaining lines continue to be processed.

从 3.15 版起已弃用，将在 3.20 版中移除: Decoding `name.pth` files in any encoding other than `utf-8-sig` is deprecated in Python 3.15, and support for decoding from the locale encoding will be removed in Python 3.20.

`import` lines in `name.pth` files are deprecated and will be silently ignored in Python 3.18 and 3.19. In Python 3.20 a warning will be produced for `import` lines in `name.pth` files.

## Startup entry points (`.start` files)

Added in version 3.15.

A startup entry point file is a file whose name has the form `name.start` and exists in one of the site-packages directories described above. Each file specifies entry points to be called during interpreter startup, using the `pkg.mod:callable` syntax understood by `pkgutil.resolve_name()`.

Each non-blank line that does not begin with `#` must contain an entry point reference in the form `pkg.mod:callable`. The colon and callable portion are mandatory. Each callable is invoked with no arguments, and any return value is discarded.

`.start` files are processed after all `.pth` path extensions have been applied to `sys.path`, ensuring that paths are available before any startup code runs.

Unlike `sys.path` extensions from `.pth` files, duplicate entry points are not de-duplicated --- if an entry point appears more than once, it will be called more than once.

If an exception occurs during resolution or invocation of an entry point, a traceback is printed to `sys.stderr` and processing continues with the remaining entry points.

`.start` files must be encoded in UTF-8.

PEP 829 defined the original specification for these features.

备注

If a `name.start` file exists alongside a `name.pth` file with the same base name, any `import` lines in the `.pth` file are ignored in favor of the entry points in the `.start` file.

备注

Executable lines (`import` lines in `name.pth` files and `name.start` file entry points) are always run at Python startup (unless `-S` is given to disable the `site.py` module entirely), regardless of whether a particular module is actually going to be used.

备注

`name.start` files invoke `pkgutil.resolve_name()` with `strict=True`, which requires the full `pkg.mod:callable` form.

## Startup file examples

For example, suppose `sys.prefix` and `sys.exec_prefix` are set to `/usr/local`. The Python X.Y library is then installed in `/usr/local/lib/pythonX.Y`. Suppose this has a subdirectory `/usr/local/lib/pythonX.Y/site-packages` with three sub-subdirectories, `foo`, `bar` and `spam`, and two path configuration files, `foo.pth` and `bar.pth`. Assume `foo.pth` contains the following:

    # foo 包配置

    foo
    bar
    bletch

并且 `bar.pth` 包含:

    # bar 包配置

    bar

则下面特定版本目录将以如下顺序被添加到 `sys.path`:

    /usr/local/lib/pythonX.Y/site-packages/bar
    /usr/local/lib/pythonX.Y/site-packages/foo

请注意 `bletch` 已被省略因为它并不存在；`bar` 目录在 `foo` 目录之前因为 `bar.pth` 按字母顺序排在 `foo.pth` 之前；而 `spam` 已被省略因为它在两个路径配置文件中都未被提及。

让我们假设还有一个 `foo.start` 文件包含以下内容:

    # foo 包启动代码

    foo.submod:initialize

现在，当 `sys.path` 像上面那样扩展之后，并在 Python 将控制权交给用户代码之前，`foo.submod` 模块将被导入且该模块的 `initialize()` 函数将被调用。

## 将 `.pth` 文件中的 `import` 行迁移至 `.start` 文件

如果你的包目前带有 `name.pth` 文件，你可以保持所有 `sys.path` 扩展行不变。 只有 `import` 行需要迁移。

To migrate, create a callable (taking zero arguments) within an importable module in your package. Reference it as a `pkg.mod:callable` entry point in a matching `name.start` file. Move everything on your `import` line after the first semi-colon into the `callable()` function.

If your package must straddle older Pythons that do not support PEP 829 and newer Pythons that do, change the `import` lines in your `name.pth` to use the following form:

    import pkg.mod; pkg.mod.callable()

Older Pythons will execute these `import` lines, while newer Pythons will ignore them in favor of the `name.start` file. After the straddling period, remove all `import` lines from your `.pth` files.

## `sitecustomize`

After these path manipulations, an attempt is made to import a module named `sitecustomize`, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an `ImportError` or its subclass exception, and the exception's `name` attribute equals `'sitecustomize'`, it is silently ignored. If Python is started without output streams available, as with `pythonw.exe` on Windows (which is used by default to start IDLE), attempted output from `sitecustomize` is ignored. Any other exception causes a silent and perhaps mysterious failure of the process.

## `usercustomize`

After this, an attempt is made to import a module named `usercustomize`, which can perform arbitrary user-specific customizations, if `ENABLE_USER_SITE` is true. This file is intended to be created in the user site-packages directory (see below), which is part of `sys.path` unless disabled by `-s`. If this import fails with an `ImportError` or its subclass exception, and the exception's `name` attribute equals `'usercustomize'`, it is silently ignored.

Note that for some non-Unix systems, `sys.prefix` and `sys.exec_prefix` are empty, and the path manipulations are skipped; however the import of `sitecustomize` and `usercustomize` is still attempted.

## Readline 配置

On systems that support `readline`, this module will also import and configure the `rlcompleter` module, if Python is started in interactive mode and without the `-S` option. The default behavior is to enable tab completion and to use `~/.python_history` as the history save file. To disable it, delete (or override) the `sys.__interactivehook__` attribute in your `sitecustomize` or `usercustomize` module or your `PYTHONSTARTUP` file.

在 3.4 版本发生变更: rlcompleter 和 history 会被自动激活。

## 模块内容

site.PREFIXES

  site-packages 目录的前缀列表。

site.ENABLE_USER_SITE

  显示用户 site-packages 目录状态的旗标。`True` 意味着它被启用并被添加到 `sys.path`。`False` 意味着它按照用户请求被禁用 (通过 `-s` 或 `PYTHONNOUSERSITE`)。`None` 意味着它因安全理由（user 或 group id 和 effective id 之间不匹配）或是被管理员所禁用。

site.USER_SITE

  运行中的 Python 的用户级 site-packages 的路径。它可以为 `None`，如果 `getusersitepackages()` 尚未被调用的话。默认值在 UNIX 和 macOS 非框架构建版上为 `~/.local/lib/pythonX.Y[t]/site-packages`，在 macOS 框架构建版上为 `~/Library/Python/X.Y/lib/python/site-packages`，而在 Windows 上为 `%APPDATA%\Python\PythonXY\site-packages`。可选的 "t" 表示自由线程构建版。此目录属于 site 目录，这意味着其中的 `.pth` 文件将会被处理。

site.USER_BASE

  用户级 site-packages 的基准目录的路径。如果尚未调用 `getuserbase()` 则它可以为 `None`。默认值在 Unix 和 macOS 非框架编译版上为 `~/.local`，在 macOS 框架编译版上为 `~/Library/Python/X.Y`，而在 Windows 上则为 `%APPDATA%\Python`。 这个值会被用于计算针对 用户安装方案 的脚本、数据文件、Python 模块等的安装目录。 另请参阅 `PYTHONUSERBASE`。

site.main()

  将所有的标准站点专属目录添加到模块搜索路径。这个函数会在导入此模块时被自动调用，除非 Python 解释器启动时附带了 `-S` 旗标。

  在 3.3 版本发生变更: 这个函数曾会被无条件调用。

site.addsitedir(sitedir, known_paths=None, *, defer_processing_start_files=False)

  Add a directory to sys.path and parse the `.pth` and `.start` files found in that directory. Typically used in `sitecustomize` or `usercustomize` (see above).

  The known_paths argument is an optional set of case-normalized paths used to prevent duplicate `sys.path` entries. When `None` (the default), the set is built from the current `sys.path`.

  While `.pth` and `.start` files are always parsed, set defer_processing_start_files to `True` to prevent processing the startup data found in those files, so that you can process them explicitly (this is typically used by the `main()` function).

  在 3.15 版本发生变更: Also processes `.start` files. See Startup entry points (.start files). All `.pth` and `.start` files are now read and accumulated before any path extensions, `import` line execution, or entry point invocations take place.

site.getsitepackages()

  返回包含所有全局 site-packages 目录的列表。

  Added in version 3.2.

site.getuserbase()

  返回用户基准目录的路径 `USER_BASE`。如果它尚未被初始化，则此函数还将参照 `PYTHONUSERBASE` 来设置它。

  Added in version 3.2.

site.getusersitepackages()

  返回用户专属 site-packages 目录的路径 `USER_SITE`。如果它尚未被初始化，则此函数还将参照 `USER_BASE` 来设置它。要确定用户专属 site-packages 是否已被添加到 `sys.path` 则应当使用 `ENABLE_USER_SITE`.

  Added in version 3.2.

## 命令行接口

The `site` module also provides a way to get the user directories from the command line:

    $ python -m site --user-site
    /home/user/.local/lib/python3.11/site-packages

如果它被不带参数地调用，它将在标准输出打印 `sys.path` 的内容，再打印 `USER_BASE` 的值以及该目录是否存在，然后打印 `USER_SITE` 的相应信息，最后打印 `ENABLE_USER_SITE` 的值。

--user-base

  输出用户基准目录的路径。

--user-site

  输出用户 site-packages 目录的路径。

如果同时给出了两个选项，则将打印用户基准目录和用户站点信息（总是按此顺序），并以 `os.pathsep` 分隔。

如果给出了其中一个选项，脚本将退出并返回以下值中的一个：如果用户级 site-packages 目录被启用则为 `0`，如果它被用户禁用则为 `1`，如果它因安全理由或被管理员禁用则为 `2`，如果发生错误则为大于 2 的值。

参见

- PEP 370 -- 分用户的 site-packages 目录

- PEP 829 -- 启动入口点与 `.pth` 文件中导入行的弃用

- sys.path 模块搜索路径的初始化 -- `sys.path` 的初始化。