# 解释器初始化和最终化

请参阅 Python 初始化配置 了解如何在初始化之前配置解释器的详情。

## Before Python initialization

In an application embedding Python, the `Py_Initialize()` function must be called before using any other Python/C API functions; with the exception of a few functions and the global configuration variables.

在初始化 Python 之前，可以安全地调用以下函数：

- 初始化解释器的函数：

  - `Py_Initialize()`

  - `Py_InitializeEx()`

  - `Py_InitializeFromConfig()`

  - `Py_BytesMain()`

  - `Py_Main()`

  - 运行时预初始化相关函数在 Python 初始化配置 中介绍

- 配置函数：

  - `PyImport_AppendInittab()`

  - `PyImport_ExtendInittab()`

  - `PyInitFrozenExtensions()`

  - `PyMem_SetAllocator()`

  - `PyMem_SetupDebugHooks()`

  - `PyObject_SetArenaAllocator()`

  - `Py_SetProgramName()`

  - `Py_SetPythonHome()`

  - 配置相关函数在 Python 初始化配置 中介绍

- 信息函数：

  - `Py_IsInitialized()`

  - `PyMem_GetAllocator()`

  - `PyObject_GetArenaAllocator()`

  - `Py_GetBuildInfo()`

  - `Py_GetCompiler()`

  - `Py_GetCopyright()`

  - `Py_GetPlatform()`

  - `Py_GetVersion()`

  - `Py_IsInitialized()`

- 工具：

  - `Py_DecodeLocale()`

  - 状态报告和工具相关函数在 Python 初始化配置 中介绍

- 内存分配器：

  - `PyMem_RawMalloc()`

  - `PyMem_RawRealloc()`

  - `PyMem_RawCalloc()`

  - `PyMem_RawFree()`

- 同步：

  - `PyMutex_Lock()`

  - `PyMutex_Unlock()`

备注

Despite their apparent similarity to some of the functions listed above, the following functions should not be called before the interpreter has been initialized: `Py_EncodeLocale()`, `PyEval_InitThreads()`, and `Py_RunMain()`.

## 全局配置变量

Python 有负责控制全局配置中不同特性和选项的变量。这些标志默认被 命令行选项 控制。

当一个选项设置一个旗标时，该旗标的值将是设置选项的次数。例如，`-b` 会将 `Py_BytesWarningFlag` 设为 1 而 `-bb` 会将 `Py_BytesWarningFlag` 设为 2。

int Py_BytesWarningFlag

  此 API 仅为向下兼容而保留：应当改为设置 `PyConfig.bytes_warning`，参见 Python 初始化配置。

  当将 `bytes` 或 `bytearray` 与 `str` 比较或者将 `bytes` 与 `int` 比较时发出警告。如果大于等于 `2` 则报错。

  由 `-b` 选项设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_DebugFlag

  此 API 仅为向下兼容而保留：应当改为设置 `PyConfig.parser_debug`，参见 Python 初始化配置。

  开启解析器调试输出（限专家使用，依赖于编译选项）。

  由 `-d` 选项和 `PYTHONDEBUG` 环境变量设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_DontWriteBytecodeFlag

  此 API 仅为向下兼容而保留：应当改为设置 `PyConfig.write_bytecode`，参见 Python 初始化配置。

  如果设置为非零，Python 不会在导入源代码时尝试写入 `.pyc` 文件。

  由 `-B` 选项和 `PYTHONDONTWRITEBYTECODE` 环境变量设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_FrozenFlag

  此 API 仅为向下兼容而保留：应当改为设置 `PyConfig.pathconfig_warnings`，参见 Python 初始化配置。

  由 `_freeze_module` 和 `frozenmain` 程序使用的私有旗标。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_HashRandomizationFlag

  此 API 仅为向下兼容而保留：应当改为设置 `PyConfig.hash_seed` 和 `PyConfig.use_hash_seed`，参见 Python 初始化配置。

  如果 `PYTHONHASHSEED` 环境变量被设为非空字符串则设为 `1`。

  如果该旗标为非零值，则读取 `PYTHONHASHSEED` 环境变量来初始化加密哈希种子。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_IgnoreEnvironmentFlag

  此 API 仅为向下兼容而保留：应当改为设置 `PyConfig.use_environment`，参见 Python 初始化配置。

  忽略所有 `PYTHON*` 环境变量，例如可能设置的 `PYTHONPATH` 和 `PYTHONHOME` 环境变量。

  由 `-E` 和 `-I` 选项设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_InspectFlag

  此 API 被保留用于向下兼容：应当改为采用设置 `PyConfig.inspect`，参见 Python 初始化配置 文档。

  当将脚本作为第一个参数传入或是使用了 `-c` 选项时，则会在执行该脚本或命令后进入交互模式，即使在 `sys.stdin` 并非一个终端时也是如此。

  由 `-i` 选项和 `PYTHONINSPECT` 环境变量设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_InteractiveFlag

  此 API 被保留用于向下兼容：应当改为采用设置 `PyConfig.interactive`，参见 Python 初始化配置。

  由 `-i` 选项设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_IsolatedFlag

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.isolated`，参见 Python 初始化配置 文档。

  以隔离模式运行 Python。在隔离模式下 `sys.path` 将不包含脚本的目录或用户的 site-packages 目录。

  由 `-I` 选项设置。

  Added in version 3.4.

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_LegacyWindowsFSEncodingFlag

  此 API 被保留用于向下兼容：应当改为设置 `PyPreConfig.legacy_windows_fs_encoding`，参见 Python 初始化配置。

  如果该旗标为非零值，则使用 `mbcs` 编码和 `replace` 错误处理器，而不是 UTF-8 编码和 `surrogatepass` 错误处理器作为 filesystem encoding and error handler。

  如果 `PYTHONLEGACYWINDOWSFSENCODING` 环境变量被设为非空字符串则设为 `1`。

  更多详情请参阅 PEP 529。

  适用范围: Windows.

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_LegacyWindowsStdioFlag

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.legacy_windows_stdio`，参见 Python 初始化配置。

  如果该旗标为非零值，则会使用 `io.FileIO` 而不是 `io._WindowsConsoleIO` 作为 `sys` 标准流。

  如果 `PYTHONLEGACYWINDOWSSTDIO` 环境变量被设为非空字符串则设为 `1`。

  有关更多详细信息，请参阅 PEP 528。

  适用范围: Windows.

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_NoSiteFlag

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.site_import`，参见 Python 初始化配置。

  禁用 `site` 的导入及其所附带的基于站点对 `sys.path` 的操作。如果 `site` 会在稍后被显式地导入也会禁用这些操作 (如果你希望触发它们则应调用 `site.main()`)。

  由 `-S` 选项设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_NoUserSiteDirectory

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.user_site_directory`，参见 Python 初始化配置。

  不要将 `用户 site-packages 目录` 添加到 `sys.path`。

  由 `-s` 和 `-I` 选项以及 `PYTHONNOUSERSITE` 环境变量设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_OptimizeFlag

  此 API 被保留用于向下兼容：应当改为 `PyConfig.optimization_level`，参见 Python 初始化配置。

  由 `-O` 选项和 `PYTHONOPTIMIZE` 环境变量设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_QuietFlag

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.quiet`，参见 Python 初始化配置 文档。

  即使在交互模式下也不显示版权和版本信息。

  由 `-q` 选项设置。

  Added in version 3.2.

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_UnbufferedStdioFlag

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.buffered_stdio`，参见 Python 初始化配置。

  强制 stdout 和 stderr 流不带缓冲。

  由 `-u` 选项和 `PYTHONUNBUFFERED` 环境变量设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

int Py_VerboseFlag

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.verbose`，参见 Python 初始化配置 文档。

  每次初始化模块时打印一条消息，显示加载模块的位置（文件名或内置模块）。如果大于或等于 `2`，则为搜索模块时检查的每个文件打印一条消息。 此外还会在退出时提供模块清理信息。

  由 `-v` 选项和 `PYTHONVERBOSE` 环境变量设置。

  从 3.12 版起已弃用，将在 3.15 版中移除.

## 初始化和最终化解释器

void Py_Initialize()
  属于 稳定 ABI.

  Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; see Before Python Initialization for the few exceptions.

  这将初始化已加载的模块表 (`sys.modules`)，并创建基础模块 `builtins`, `__main__` 和 `sys`。它还会初始化模块搜索路径 (`sys.path`)。它不会设置 `sys.argv`；对于此设置请使用 Python 初始化配置 API。当第二次被调用时（在未先调用 `Py_FinalizeEx()` 的情况下）将不会执行任何操作。它没有返回值；如果初始化失败则会发生致命错误。

  使用 `Py_InitializeFromConfig()` 来自定义 Python 初始化配置。

  备注

  在 Windows 上，将控制台模式从 `O_TEXT` 改为 `O_BINARY`，这还将影响使用 C 运行时的非 Python 的控制台使用。

void Py_InitializeEx(int initsigs)
  属于 稳定 ABI.

  如果 initsigs 为 `1` 则此函数的工作方式与 `Py_Initialize()` 类似。如果 initsigs 为 `0`，它将跳过信号处理器的初始化注册，这在将 CPython 作为更大应用程序的一部分嵌入时会很有用处。

  使用 `Py_InitializeFromConfig()` 来自定义 Python 初始化配置。

PyStatus Py_InitializeFromConfig(const PyConfig *config)

  根据 config 配置来初始化 Python，如 使用 PyConfig 初始化 中所描述的。

  请参阅 Python 初始化配置 一节了解有关预初始化解释器，填充运行时配置结构体，以及查询所返回的状态结构体的详情。

int Py_IsInitialized()
  属于 稳定 ABI.

  如果 Python 解释器已初始化，则返回真值（非零）；否则返回假值（零）。在调用 `Py_FinalizeEx()` 之后，此函数将返回假值直到 `Py_Initialize()` 再次被调用。

int Py_IsFinalizing()
  属于 稳定 ABI 自 3.13 版起.

  如果主 Python 解释器 正在关闭 则返回真（非零）值。在其他情况下返回假（零）值。

  Added in version 3.13.

int Py_FinalizeEx()
  属于 稳定 ABI 自 3.6 版起.

  撤销由 `Py_Initialize()` 所执行的所有初始化操作及后续对 Python/C API 函数的使用，并销毁自上次调用 `Py_Initialize()` 以来创建但尚未销毁的所有子解释器（参见下面 `Py_NewInterpreter()` 一节）。 当第二次调用（事先没有再次对 `Py_Initialize()` 进行调用）时将无任何操作。

  由于这是 `Py_Initialize()` 的逆向操作，因而它应当在激活同一解释器的同一线程中被调用。这意味着主线程和主解释器。当 `Py_RunMain()` 仍然运行时则绝不应调用此函数。

  通常返回值为 `0`。如果在最终化（刷新缓冲的数据）期间发生错误，则返回 `-1`。

  请注意 Python 会尽最大努力释放 Python 解释器所分配的所有内存。 因此，任何 C 扩展都应当确保在对 `Py_Initialize()` 的后续调用中使用此前分配的所有 PyObjects 之前正确地清理它们。 否则可能导致安全漏洞和不正确的行为。

  提供此函数的原因有很多。嵌入应用程序可能希望重新启动 Python，而不必重新启动应用程序本身。从动态可加载库（或 DLL）加载 Python 解释器的应用程序可能希望在卸载 DLL 之前释放 Python 分配的所有内存。在搜索应用程序内存泄漏的过程中，开发人员可能希望在退出应用程序之前释放 Python 分配的所有内存。

  已知问题与注意事项： 模块及模块内对象的销毁顺序是随机的，这可能导致析构函数（`__del__()` 方法）在依赖其他对象（甚至函数）或模块时执行失败； 由 Python 动态加载的扩展模块不会被卸载； Python 解释器分配的少量内存可能无法释放（如发现内存泄漏请提交报告）； 对象间循环引用占用的内存不会被释放； 无论引用计数如何，所有驻留字符串（interned strings）都将被释放； 扩展模块分配的部分内存可能无法释放； 某些扩展在初始化例程被多次调用时可能出现异常行为（当应用程序多次调用 `Py_Initialize()` 和 `Py_FinalizeEx()` 时会发生这种情况）； `Py_FinalizeEx()` 不可被自身递归调用，因此任何可能作为解释器关闭流程一部分的代码（如 `atexit` 处理器、对象终结器、或在刷新 stdout/stderr 文件时运行的代码）都不得调用该函数。

  引发一个不带参数的 审计事件 `cpython._PySys_ClearAuditHooks`。

  Added in version 3.6.

void Py_Finalize()
  属于 稳定 ABI.

  这是一个不考虑返回值的 `Py_FinalizeEx()` 的向下兼容版本。

int Py_BytesMain(int argc, char **argv)
  属于 稳定 ABI 自 3.8 版起.

  类似于 `Py_Main()` 但 argv 是一个字节串数组，允许调用方应用程序将文本解码步骤委托给 CPython 运行时。

  Added in version 3.8.

int Py_Main(int argc, wchar_t **argv)
  属于 稳定 ABI.

  标准解释器的主程序，封装了完整的初始化/最终化循环，以及一些附加行为以实现从环境和命令行读取配置设置，然后按照 命令行 的规则执行 `__main__`。

  这适用于希望支持完整 CPython 命令行界面的程序，而不仅是在更大应用程序中嵌入 Python 运行时。

  argc 和 argv 形参与传给 C 程序的 `main()` 函数的形参类似，不同之处在于 argv 的条目会先使用 `Py_DecodeLocale()` 转换为 `wchar_t`。 还有一个重要的注意事项是参数列表条目可能会被修改为指向并非被传入的字符串（不过，参数列表所指向的字符串内容不会被修改）。

  如果参数列表不是表示一个有效的 Python 命令行则返回值为 `2`，否则将与 `Py_RunMain()` 相同。

  在记录于 运行时配置 一节的 CPython 运行时配置 API 文档中（不考虑错误处理），`Py_Main` 大致相当于:

      PyConfig config;
      PyConfig_InitPythonConfig(&config);
      PyConfig_SetArgv(&config, argc, argv);
      Py_InitializeFromConfig(&config);
      PyConfig_Clear(&config);

      Py_RunMain();

  在正常使用中，嵌入式应用程序将调用此函数 而不是 直接调用 `Py_Initialize()`, `Py_InitializeEx()` 或 `Py_InitializeFromConfig()`，并且所有设置都将如本文档的其他部分所描述的那样被应用。 如果此函数改在某个先前的运行时初始化 API 调用 之后 被调用，那么到底那个环境和命令行配置会被更新将取决于具体的版本（因为它要依赖当运行时被初始化时究竟有哪些设置在它们已被设置一次之后是正确地支持被修改的）。

int Py_RunMain(void)

  在完整配置的 CPython 运行时中执行主模块。

  执行在命令行或配置中指定的命令 (`PyConfig.run_command`)、脚本 (`PyConfig.run_filename`) 或模块 (`PyConfig.run_module`)。 如果这些值均未设置，则使用 `__main__` 模块的全局命名空间来运行交互式 Python 提示符 (REPL)。

  如果 `PyConfig.inspect` 未设置（默认），则当解释器正常退出（也就是说未引发异常）时返回值将为 `0`，未处理的 `SystemExit` 的退出状态，或者对于任何其他未处理异常则为 `1`。

  如果 `PyConfig.inspect` 已设置（例如当使用了 `-i` 选项时），则当解释器退出时执行将不会返回，而是会使用 `__main__` 模块的全局命名空间在交互式 Python 提示符 (REPL) 中恢复。 如果解释器附带异常退出，该异常将在 REPL 会话中被立即引发。随后函数的返回值将由 REPL 会话 的终结方式来决定：`0`, `1` 或者 `SystemExit` 的状态，如上文所指明的。

  此函数总是会在它返回之前最终化 Python 解释器。

  请参阅 Python 配置 查看一个使用 `Py_RunMain()` 在隔离模式下始终运行定制的 Python 的示例。

int PyUnstable_AtExit(PyInterpreterState *interp, void (*func)(void*), void *data)
  这是 不稳定 API。它可能在次要版本中不经警告地被更改。

  为目标解释器 interp 注册一个 `atexit` 回调。这与 `Py_AtExit()` 类似，但它接受一个显式的解释器和用于回调的数据指针。

  必须有一个对应 interp 的 attached thread state。

  Added in version 3.13.

## 有关运行时最终化的注意事项

在 interpreter shutdown 的后期阶段，系统会先尝试等待非守护线程退出（此过程可能被 `KeyboardInterrupt` 中断），并执行 `atexit` 注册的函数。此时运行时状态会被标记为 正在终结: `Py_IsFinalizing()` 和 `sys.is_finalizing()` 均返回真值。 在此状态下，仅允许发起终结流程的 终结线程 （通常为主线程）获取 GIL。

如果非终结线程的其他线程在终结阶段尝试显式或隐式附加 thread state，该线程将进入 永久阻塞状态 ——直至程序退出前都无法恢复。 多数情况下这不会造成危害，但如果终结过程的后续阶段试图获取被阻塞线程持有的锁，或以其他方式等待该线程响应，则可能引发死锁。

粗暴？确实如此。但这样做能避免随机崩溃，以及当这些线程在 CPython 3.13 及更早版本中被强制退出时，调用栈上游可能出现的 C++ 资源未释放问题。CPython 运行时的 thread state C API 在设计之初就未考虑在 thread state 附加阶段提供错误报告或处理机制，因此无法优雅处理这种情况。若要改变现状，就需要新增稳定的 C API，并重写 CPython 生态中绝大多数 C 代码来适配这些带错误处理的新 API。

## 进程级参数

void Py_SetProgramName(const wchar_t *name)
  属于 稳定 ABI.

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.program_name`，参见 Python 初始化配置。

  如果要调用该函数，应当在首次调用 `Py_Initialize()` 之前调用它。它将告诉解释器程序的 `main()` 函数的 `argv[0]` 参数的值（转换为宽字符）。 `Py_GetPath()` 和下面的某些其他函数会使用它在相对于解释器的位置上查找可执行文件的 Python 运行时库。默认值是 `'python'`。参数应当指向静态存储中的一个以零值结束的宽字符串，其内容在程序执行期间不会发生改变。Python 解释器中的任何代码都不会改变该存储的内容。

  使用 `Py_DecodeLocale()` 解码字节串以得到一个 wchar_t* 字符串。

  从 3.11 版起已弃用，将在 3.15 版中移除.

wchar_t *Py_GetProgramName()
  属于 稳定 ABI.

  返回用 `PyConfig.program_name` 设置的程序名称，或默认名称。返回的字符串指向静态存储；调用方不应修改其值。

  此函数不应在 `Py_Initialize()` 之前被调用，否则将返回 `NULL`。

  在 3.10 版本发生变更: 现在如果它在 `Py_Initialize()` 之前被调用将返回 `NULL`。

  从 3.13 版起已弃用，将在 3.15 版中移除: 改用 `PyConfig_Get("executable")` (`sys.executable`) 对应的值。

wchar_t *Py_GetPrefix()
  属于 稳定 ABI.

  返回针对已安装的独立于平台文件的 prefix。这是通过基于使用 `PyConfig.program_name` 设置的程序名称和某些环境变量所派生的一系列复杂规则来获取的；举例来说，如果程序名称为 `'/usr/local/bin/python'`，则 prefix 为 `'/usr/local'`。返回的字符串将指向静态存储；调用方不应修改其值。这对应于最高层级 `Makefile` 中的 prefix 变量以及在编译时传给 configure 脚本的 `--prefix` 参数。该值将作为 `sys.base_prefix` 供 Python 代码使用。它仅适用于 Unix。 另请参见下一个函数。

  此函数不应在 `Py_Initialize()` 之前被调用，否则将返回 `NULL`。

  在 3.10 版本发生变更: 现在如果它在 `Py_Initialize()` 之前被调用将返回 `NULL`。

  从 3.13 版起已弃用，将在 3.15 版中移除: 改用 `PyConfig_Get("base_prefix")` (`sys.base_prefix`)。如果需要处理 虚拟环境 则使用 `PyConfig_Get("prefix")` (`sys.prefix`) 对应的值。

wchar_t *Py_GetExecPrefix()
  属于 稳定 ABI.

  返回针对已安装的 依赖于 平台文件的 exec-prefix。这是通过基于使用 `PyConfig.program_name` 设置的程序名称和某些环境变量所派生的一系列复杂规则来获取的；举例来说，如果程序名称为 `'/usr/local/bin/python'`，则 exec-prefix 为 `'/usr/local'`。 返回的字符串将指向静态存储；调用方不应修改其值。这对应于最高层级 `Makefile` 中的 exec_prefix 变量以及在编译时传给 configure 脚本的 `--exec-prefix` 参数。该值将作为 `sys.base_exec_prefix` 供 Python 代码使用。它仅适用于 Unix。

  背景：当依赖于平台的文件（如可执行文件和共享库）是安装于不同的目录树中的时候 exec-prefix 将会不同于 prefix。 在典型的安装中，依赖于平台的文件可能安装于 `/usr/local/plat` 子目录树而独立于平台的文件可能安装于 `/usr/local` 目录。

  总而言之，平台是一组硬件和软件资源的组合，例如所有运行 Solaris 2.x 操作系统的 Sparc 机器会被视为相同平台，但运行 Solaris 2.x 的 Intel 机器是另一种平台，而运行 Linux 的 Intel 机器又是另一种平台。相同操作系统的不同主要发布版通常也会构成不同的平台。 非 Unix 操作系统的情况又有所不同；这类系统上的安装策略差别巨大因此 prefix 和 exec-prefix 是没有意义的，并将被设为空字符串。 请注意已编译的 Python 字节码是独立于平台的（但并不独立于它们编译时所使用的 Python 版本！）

  系统管理员知道如何配置 mount 或 automount 程序以在平台间共享 `/usr/local` 而让 `/usr/local/plat` 成为针对不同平台的不同文件系统。

  此函数不应在 `Py_Initialize()` 之前被调用，否则将返回 `NULL`。

  在 3.10 版本发生变更: 现在如果它在 `Py_Initialize()` 之前被调用将返回 `NULL`。

  从 3.13 版起已弃用，将在 3.15 版中移除: 改用 `PyConfig_Get("base_exec_prefix")` (`sys.base_exec_prefix`)。如果需要处理 虚拟环境 则使用 `PyConfig_Get("exec_prefix")` (`sys.exec_prefix`) 对应的值。

wchar_t *Py_GetProgramFullPath()
  属于 稳定 ABI.

  返回 Python 可执行文件的完整程序名称；这是作为基于程序名称（由 `PyConfig.program_name` 设置）派生默认模块搜索路径的附带影响计算得出的。返回的字符串将指向静态存储；调用方不应修改其值。该值将以 `sys.executable` 的名称供 Python 代码访问。

  此函数不应在 `Py_Initialize()` 之前被调用，否则将返回 `NULL`。

  在 3.10 版本发生变更: 现在如果它在 `Py_Initialize()` 之前被调用将返回 `NULL`。

  从 3.13 版起已弃用，将在 3.15 版中移除: 改用 `PyConfig_Get("executable")` (`sys.executable`) 对应的值。

wchar_t *Py_GetPath()
  属于 稳定 ABI.

  返回默认模块搜索路径；这是基于程序名称（由 `PyConfig.program_name` 设置）和某些环境变量计算得出的。 返回的字符串由一系列以依赖于平台的分隔符分开的目录名称组成。此分隔符在 Unix 和 macOS 上为 `':'`，在 Windows 上为 `';'`。返回的字符串将指向静态存储；调用方不应修改其值。列表 `sys.path` 将在解释器启动时使用该值来初始化；它可以在随后被修改（并且通常都会被修改）以变更用于加载模块的搜索路径。

  此函数不应在 `Py_Initialize()` 之前被调用，否则将返回 `NULL`。

  在 3.10 版本发生变更: 现在如果它在 `Py_Initialize()` 之前被调用将返回 `NULL`。

  从 3.13 版起已弃用，将在 3.15 版中移除: 改用 `PyConfig_Get("module_search_paths")` (`sys.path`) 对应的值。

const char *Py_GetVersion()
  属于 稳定 ABI.

  返回 Python 解释器的版本。这将为如下形式的字符串

      "3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"

  第一个单词（到第一个空格符为止）是当前的 Python 版本；前面的字符是以点号分隔的主要和次要版本号。 返回的字符串将指向静态存储；调用方不应修改其值。该值将以 `sys.version` 的名称供 Python 代码使用。

  另请参阅 `Py_Version` 常量。

const char *Py_GetPlatform()
  属于 稳定 ABI.

  返回当前平台的平台标识符。在 Unix 上，这将以操作系统的“官方”名称为基础，转换为小写形式，再加上主版本号；例如，对于 Solaris 2.x，或称 SunOS 5.x，该值将为 `'sunos5'`。在 macOS 上，它将为 `'darwin'`。在 Windows 上它将为 `'win'`。返回的字符串指向静态存储；调用方不应修改其值。Python 代码可通过 `sys.platform` 获取该值。

const char *Py_GetCopyright()
  属于 稳定 ABI.

  返回当前 Python 版本的官方版权字符串，例如

  `'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'`

  返回的字符串指向静态存储；调用者不应修改其值。Python 代码可通过 `sys.copyright` 获取该值。

const char *Py_GetCompiler()
  属于 稳定 ABI.

  返回用于编译当前 Python 版本的编译器标识信息，为带方括号的形式，例如:

      "[GCC 2.7.2.2]"

  返回的字符串指向静态存储；调用者不应修改其值。Python 代码可以从变量 `sys.version` 中获取该值。

const char *Py_GetBuildInfo()
  属于 稳定 ABI.

  Return information about the sequence number and build date and time of the current Python interpreter instance, for example

      "#67, Aug  1 1997, 22:34:28"

  返回的字符串指向静态存储；调用者不应修改其值。Python 代码可以从变量 `sys.version` 中获取该值。

void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
  属于 稳定 ABI.

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.argv`, `PyConfig.parse_argv` 和 `PyConfig.safe_path`，参见 Python 初始化配置。

  根据 argc 和 argv 设置 `sys.argv`。这些形参与传给程序的 `main()` 函数的类似，区别在于第一项应当指向要执行的脚本文件而不是 Python 解释器对应的可执行文件。如果没有要运行的脚本，则 argv 中的第一项可以为空字符串。如果此函数无法初始化 `sys.argv`，则将使用 `Py_FatalError()` 发出严重情况信号。

  如果 updatepath 为零，此函数将完成操作。如果 updatepath 为非零值，则此函数还将根据以下算法修改 `sys.path`:

  - 如果在 `argv[0]` 中传入一个现有脚本，则脚本所在目录的绝对路径将被添加到 `sys.path` 的开头。

  - 在其他情况下 (也就是说，如果 argc 为 `0` 或 `argv[0]` 未指向现有文件名)，则将在 `sys.path` 的开头添加一个空字符串，这等价于添加当前工作目录 (`"."`)。

  使用 `Py_DecodeLocale()` 解码字节串以得到一个 wchar_t* 字符串。

  另请参阅 Python 初始化配置 的 `PyConfig.orig_argv` 和 `PyConfig.argv` 成员。

  备注

  建议在出于执行单个脚本以外的目的嵌入 Python 解释器的应用传入 `0` 作为 updatepath，并在需要时更新 `sys.path` 本身。参见 CVE 2008-5983。

  在 3.1.3 之前的版本中，你可以通过在调用 `PySys_SetArgv()` 之后手动弹出第一个 `sys.path` 元素，例如使用:

      PyRun_SimpleString("import sys; sys.path.pop(0)\n");

  Added in version 3.1.3.

  从 3.11 版起已弃用，将在 3.15 版中移除.

void PySys_SetArgv(int argc, wchar_t **argv)
  属于 稳定 ABI.

  此 API 仅为向下兼容而保留：应当改为设置 `PyConfig.argv` 并改用 `PyConfig.parse_argv`，参见 Python 初始化配置。

  此函数相当于 `PySys_SetArgvEx()` 设置了 updatepath 为 `1` 除非 python 解释器启动时附带了 `-I`。

  使用 `Py_DecodeLocale()` 解码字节串以得到一个 wchar_t* 字符串。

  另请参阅 Python 初始化配置 的 `PyConfig.orig_argv` 和 `PyConfig.argv` 成员。

  在 3.4 版本发生变更: updatepath 值依赖于 `-I`。

  从 3.11 版起已弃用，将在 3.15 版中移除.

void Py_SetPythonHome(const wchar_t *home)
  属于 稳定 ABI.

  此 API 被保留用于向下兼容：应当改为设置 `PyConfig.home`，参见 Python 初始化配置 文档。

  设置默认的 "home" 目录，也就是标准 Python 库所在的位置。请参阅 `PYTHONHOME` 了解该参数字符串的含义。

  此参数应当指向静态存储中一个以零值结束的字符串，其内容在程序执行期间将保持不变。Python 解释器中的代码绝不会修改此存储中的内容。

  使用 `Py_DecodeLocale()` 解码字节串以得到一个 wchar_t* 字符串。

  从 3.11 版起已弃用，将在 3.15 版中移除.

wchar_t *Py_GetPythonHome()
  属于 稳定 ABI.

  返回默认的 "home"，就是由 `PyConfig.home` 所设置的值，或者在设置了 `PYTHONHOME` 环境变量的情况下则为该变量的值。

  此函数不应在 `Py_Initialize()` 之前被调用，否则将返回 `NULL`。

  在 3.10 版本发生变更: 现在如果它在 `Py_Initialize()` 之前被调用将返回 `NULL`。

  从 3.13 版起已弃用，将在 3.15 版中移除: 改用 `PyConfig_Get("home")` 或 `PYTHONHOME` 环境变量。