Python初始化配置
****************

3.8 新版功能.

Python 可以使用 "Py_InitializeFromConfig()" 和 "PyConfig" 结构体来初始
化。 它可以使用 "Py_PreInitialize()" 和 "PyPreConfig" 结构体来预初始化
。

有两种配置方式：

* Python 配置 可被用于构建一个定制的 Python，其行为与常规 Python 类似
  。 例如，环境变量和命令行参数可被用于配置 Python。

* 隔离配置 可被用于将 Python 嵌入到应用程序。 它将 Python 与系统隔离开
  来。 例如，环境变量将被忽略，LC_CTYPE 语言区域设置保持不变并且不会注
  册任何信号处理器。

"Py_RunMain()" 函数可被用来编写定制的 Python 程序。

参见 Initialization, Finalization, and Threads.

参见: **PEP 587** "Python 初始化配置".


示例
====

定制的 Python 的示例总是会以隔离模式运行:

   int main(int argc, char **argv)
   {
       PyStatus status;

       PyConfig config;
       PyConfig_InitPythonConfig(&config);
       config.isolated = 1;

       /* Decode command line arguments.
          Implicitly preinitialize Python (in isolated mode). */
       status = PyConfig_SetBytesArgv(&config, argc, argv);
       if (PyStatus_Exception(status)) {
           goto exception;
       }

       status = Py_InitializeFromConfig(&config);
       if (PyStatus_Exception(status)) {
           goto exception;
       }
       PyConfig_Clear(&config);

       return Py_RunMain();

   exception:
       PyConfig_Clear(&config);
       if (PyStatus_IsExit(status)) {
           return status.exitcode;
       }
       /* Display the error message and exit the process with
          non-zero exit code */
       Py_ExitStatusException(status);
   }


PyWideStringList
================

type PyWideStringList

   由 "wchar_t*" 字符串组成的列表。

   如果 *length* 为非零值，则 *items* 必须不为 "NULL" 并且所有字符串均
   必须不为 "NULL"。

   方法

   PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)

      将 *item* 添加到 *list*。

      Python 必须被预初始化以便调用此函数。

   PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item)

      将 *item* 插入到 *list* 的 *index* 位置上。

      如果 *index* 大于等于 *list* 的长度，则将 *item* 添加到 *list*。

      *index* must be greater than or equal to 0.

      Python 必须被预初始化以便调用此函数。

   结构体字段:

   Py_ssize_t length

      List 长度。

   wchar_t **items

      列表项目。


PyStatus
========

type PyStatus

   存储初始函数状态：成功、错误或退出的结构体。

   对于错误，它可以存储造成错误的 C 函数的名称。

   结构体字段:

   int exitcode

      退出码。 传给 "exit()" 的参数。

   const char *err_msg

      错误信息

   const char *func

      造成错误的函数的名称，可以为 "NULL"。

   创建状态的函数:

   PyStatus PyStatus_Ok(void)

      完成。

   PyStatus PyStatus_Error(const char *err_msg)

      带消息的初始化错误。

      *err_msg* 不可为 "NULL"。

   PyStatus PyStatus_NoMemory(void)

      内存分配失败（内存不足）。

   PyStatus PyStatus_Exit(int exitcode)

      以指定的退出代码退出 Python。

   处理状态的函数:

   int PyStatus_Exception(PyStatus status)

      状态为错误还是退出？如为真值，则异常必须被处理；例如通过调用
      "Py_ExitStatusException()"。

   int PyStatus_IsError(PyStatus status)

      结果错误吗？

   int PyStatus_IsExit(PyStatus status)

      结果是否退出？

   void Py_ExitStatusException(PyStatus status)

      如果 *status* 是一个退出码则调用 "exit(exitcode)"。如果 *status*
      是一个错误码则打印错误消息并设置一个非零退出码再退出。 必须在
      "PyStatus_Exception(status)" 为非零值时才能被调用。

注解:

  在内部，Python 将使用设置 "PyStatus.func" 的宏，而创建状态的函数则会
  将 "func" 设为 "NULL"。

示例:

   PyStatus alloc(void **ptr, size_t size)
   {
       *ptr = PyMem_RawMalloc(size);
       if (*ptr == NULL) {
           return PyStatus_NoMemory();
       }
       return PyStatus_Ok();
   }

   int main(int argc, char **argv)
   {
       void *ptr;
       PyStatus status = alloc(&ptr, 16);
       if (PyStatus_Exception(status)) {
           Py_ExitStatusException(status);
       }
       PyMem_Free(ptr);
       return 0;
   }


PyPreConfig
===========

type PyPreConfig

   用于预初始化 Python 的结构体。

   用于初始化预先配置的函数:

   void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)

      通过 Python 配置 来初始化预先配置。

   void PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)

      通过 隔离配置 来初始化预先配置。

   结构体字段:

   int allocator

      Python 内存分配器名称:

      * "PYMEM_ALLOCATOR_NOT_SET" ("0"): 不改变内存分配器 (使用默认)。

      * "PYMEM_ALLOCATOR_DEFAULT" ("1"): 默认内存分配器。

      * "PYMEM_ALLOCATOR_DEBUG" ("2"): 默认内存分配器 附带 调试钩子。

      * "PYMEM_ALLOCATOR_MALLOC" ("3"): 使用 C 库的 "malloc()"。

      * "PYMEM_ALLOCATOR_MALLOC_DEBUG" ("4"): 强制使用 "malloc()" 附带
        调试钩子。

      * "PYMEM_ALLOCATOR_PYMALLOC" ("5"): Python pymalloc 内存分配器。

      * "PYMEM_ALLOCATOR_PYMALLOC_DEBUG" ("6"): Python pymalloc 内存分
        配器 附带 调试钩子。

      如果 Python 是 "使用 --without-pymalloc 进行配置" 则
      "PYMEM_ALLOCATOR_PYMALLOC" 和 "PYMEM_ALLOCATOR_PYMALLOC_DEBUG"
      将不被支持。

      参见 Memory Management.

      默认值: "PYMEM_ALLOCATOR_NOT_SET"。

   int configure_locale

      将 LC_CTYPE 语言区域设为用户选择的语言区域。

      If equals to 0, set "coerce_c_locale" and "coerce_c_locale_warn"
      members to 0.

      参见 *locale encoding*。

      默认值: 在 Python 配置中为 "1"，在隔离配置中为 "0"。

   int coerce_c_locale

      If equals to 2, coerce the C locale.

      If equals to 1, read the LC_CTYPE locale to decide if it should
      be coerced.

      参见 *locale encoding*。

      默认值: 在 Python 配置中为 "-1"，在隔离配置中为 "0"。

   int coerce_c_locale_warn

      如为非零值，则会在 C 语言区域被强制转换时发出警告。

      默认值: 在 Python 配置中为 "-1"，在隔离配置中为 "0"。

   int dev_mode

      If non-zero, enables the Python Development Mode: see
      "PyConfig.dev_mode".

      默认值: 在 Python 模式中为 "-1"，在隔离模式中为 "0"。

   int isolated

      隔离模式：参见 "PyConfig.isolated"。

      默认值: 在 Python 模式中为 "0"，在隔离模式中为 "1"。

   int legacy_windows_fs_encoding

      如为非零值:

      * 设置 "PyPreConfig.utf8_mode" 为 "0",

      * 设置 "PyConfig.filesystem_encoding" 为 ""mbcs"",

      * 设置 "PyConfig.filesystem_errors" 为 ""replace"".

      初始化来自 "PYTHONLEGACYWINDOWSFSENCODING" 的环境变量值。

      仅在 Windows 上可用。 "#ifdef MS_WINDOWS" 宏可被用于 Windows 专
      属的代码。

      默认值: "0".

   int parse_argv

      如为非零值，"Py_PreInitializeFromArgs()" 和
      "Py_PreInitializeFromBytesArgs()" 将以与常规 Python 解析命令行参
      数的相同方式解析其 "argv" 参数：参见 命令行参数。

      默认值: 在 Python 配置中为 "1"，在隔离配置中为 "0"。

   int use_environment

      使用 环境变量? 参见 "PyConfig.use_environment"。

      默认值: 在 Python 配置中为 "1" 而在隔离配置中为 "0"。

   int utf8_mode

      如为非零值，则启用 Python UTF-8 模式。

      Set by the "-X utf8" command line option and the "PYTHONUTF8"
      environment variable.

      默认值: 在 Python 配置中为 "-1" 而在隔离配置中为 "0"。


使用 PyPreConfig 预初始化 Python
================================

Python 的预初始化:

* 设置 Python 内存分配器 ("PyPreConfig.allocator")

* 配置 LC_CTYPE 语言区域 (*locale encoding*)

* 设置 Python UTF-8 模式 ("PyPreConfig.utf8_mode")

当前的预配置 ("PyPreConfig" 类型) 保存在 "_PyRuntime.preconfig" 中。

用于预初始化 Python 的函数：

PyStatus Py_PreInitialize(const PyPreConfig *preconfig)

   根据 *preconfig* 预配置来预初始化 Python。

   *preconfig* 不可为 "NULL"。

PyStatus Py_PreInitializeFromBytesArgs(const PyPreConfig *preconfig, int argc, char *const *argv)

   根据 *preconfig* 预配置来预初始化 Python。

   如果 *preconfig* 的 "parse_argv" 为非零值则解析 *argv* 命令行参数（
   字节串）。

   *preconfig* 不可为 "NULL"。

PyStatus Py_PreInitializeFromArgs(const PyPreConfig *preconfig, int argc, wchar_t *const *argv)

   根据 *preconfig* 预配置来预初始化 Python。

   如果 *preconfig* 的 "parse_argv" 为非零值则解析 *argv* 命令行参数（
   宽字符串）。

   *preconfig* 不可为 "NULL"。

调用方要负责使用 "PyStatus_Exception()" 和 "Py_ExitStatusException()"
来处理异常（错误或退出）。

对于 Python 配置 ("PyPreConfig_InitPythonConfig()")，如果 Python 是用
命令行参数初始化的，那么在预初始化 Python 时也必须传递命令行参数，因为
它们会对编码格式等预配置产生影响。 例如，"-X utf8" 命令行选项将启用
Python UTF-8 模式。

"PyMem_SetAllocator()" 可在 "Py_PreInitialize()" 之后、
"Py_InitializeFromConfig()" 之前被调用以安装自定义的内存分配器。 如果
"PyPreConfig.allocator" 被设为 "PYMEM_ALLOCATOR_NOT_SET" 则可在
"Py_PreInitialize()" 之前被调用。

像 "PyMem_RawMalloc()" 这样的 Python 内存分配函数不能在 Python 预初始
化之前使用，而直接调用 "malloc()" 和 "free()" 则始终会是安全的。
"Py_DecodeLocale()" 不能在 Python 预初始化之前被调用。

使用预初始化来启用 Python UTF-8 模式 的例子:

   PyStatus status;
   PyPreConfig preconfig;
   PyPreConfig_InitPythonConfig(&preconfig);

   preconfig.utf8_mode = 1;

   status = Py_PreInitialize(&preconfig);
   if (PyStatus_Exception(status)) {
       Py_ExitStatusException(status);
   }

   /* at this point, Python speaks UTF-8 */

   Py_Initialize();
   /* ... use Python API here ... */
   Py_Finalize();


PyConfig
========

type PyConfig

   包含了大部分用于配置 Python 的形参的结构体。

   在完成后，必须使用 "PyConfig_Clear()" 函数来释放配置内存。

   结构体方法:

   void PyConfig_InitPythonConfig(PyConfig *config)

      通过 Python 配置 来初始化配置。

   void PyConfig_InitIsolatedConfig(PyConfig *config)

      通过 隔离配置 来初始化配置。

   PyStatus PyConfig_SetString(PyConfig *config, wchar_t *const *config_str, const wchar_t *str)

      将宽字符串 *str* 拷贝至 "*config_str"。

      在必要时 预初始化 Python。

   PyStatus PyConfig_SetBytesString(PyConfig *config, wchar_t *const *config_str, const char *str)

      使用 "Py_DecodeLocale()" 对 *str* 进行解码并将结果设置到
      "*config_str"。

      在必要时 预初始化 Python。

   PyStatus PyConfig_SetArgv(PyConfig *config, int argc, wchar_t *const *argv)

      根据宽字符串列表 *argv* 设置命令行参数 (*config* 的 "argv" 成员)
      。

      在必要时 预初始化 Python。

   PyStatus PyConfig_SetBytesArgv(PyConfig *config, int argc, char *const *argv)

      根据字节串列表 *argv* 设置命令行参数 (*config* 的 "argv" 成员)。
      使用 "Py_DecodeLocale()" 对字节串进行解码。

      在必要时 预初始化 Python。

   PyStatus PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items)

      将宽字符串列表 *list* 设置为 *length* 和 *items*。

      在必要时 预初始化 Python。

   PyStatus PyConfig_Read(PyConfig *config)

      读取所有 Python 配置。

      已经初始化的字段会保持不变。

      "PyConfig_Read()" 函数只解析 "PyConfig.argv" 参数一次：在参数解
      析完成后，"PyConfig.parse_argv" 将被设为 "2"。 由于 Python 参数
      是从 "PyConfig.argv" 中剥离的，因此解析参数两次会将应用程序选项
      解析为 Python 选项。

      在必要时 预初始化 Python。

      在 3.10 版更改: "PyConfig.argv" 参数现在只会被解析一次，在参数解
      析完成后，"PyConfig.parse_argv" 将被设为 "2"，只有当
      "PyConfig.parse_argv" 等于 "1" 时才会解析参数。

   void PyConfig_Clear(PyConfig *config)

      释放配置内存

   如有必要大多数 "PyConfig" 方法将会 预初始化 Python。 在这种情况下，
   Python 预初始化配置 ("PyPreConfig") 将以 "PyConfig" 为基础。 如果要
   调整与 "PyPreConfig" 相同的配置字段，它们必须在调用 "PyConfig" 方法
   之前被设置：

   * "PyConfig.dev_mode"

   * "PyConfig.isolated"

   * "PyConfig.parse_argv"

   * "PyConfig.use_environment"

   Moreover, if "PyConfig_SetArgv()" or "PyConfig_SetBytesArgv()" is
   used, this method must be called before other methods, since the
   preinitialization configuration depends on command line arguments
   (if "parse_argv" is non-zero).

   这些方法的调用者要负责使用 "PyStatus_Exception()" 和
   "Py_ExitStatusException()" 来处理异常（错误或退出）。

   结构体字段:

   PyWideStringList argv

      命令行参数: "sys.argv"。

      将 "parse_argv" 设为 "1" 将以与普通 Python 解析 Python 命令行参
      数相同的方式解析 "argv" 再从 "argv" 中剥离 Python 参数。

      如果 "argv" 为空，则会添加一个空字符串以确保 "sys.argv" 始终存在
      并且永远不为空。

      默认值: "NULL".

      另请参阅 "orig_argv" 成员。

   wchar_t *base_exec_prefix

      "sys.base_exec_prefix".

      默认值: "NULL".

      Python 路径配置 的一部分。

   wchar_t *base_executable

      Python 基础可执行文件: "sys._base_executable"。

      由 "__PYVENV_LAUNCHER__" 环境变量设置。

      如为 "NULL" 则从 "PyConfig.executable" 设置。

      默认值: "NULL".

      Python 路径配置 的一部分。

   wchar_t *base_prefix

      "sys.base_prefix".

      默认值: "NULL".

      Python 路径配置 的一部分。

   int buffered_stdio

      If equals to 0 and "configure_c_stdio" is non-zero, disable
      buffering on the C streams stdout and stderr.

      Set to 0 by the "-u" command line option and the
      "PYTHONUNBUFFERED" environment variable.

      stdin 始终以缓冲模式打开。

      默认值: "1".

   int bytes_warning

      If equals to 1, issue a warning when comparing "bytes" or
      "bytearray" with "str", or comparing "bytes" with "int".

      If equal or greater to 2, raise a "BytesWarning" exception in
      these cases.

      由 "-b" 命令行选项执行递增。

      默认值: "0".

   int warn_default_encoding

      如为非零值，则在 "io.TextIOWrapper" 使用默认编码格式时发出
      "EncodingWarning" 警告。 详情请参阅 选择性的 EncodingWarning。

      默认值: "0".

      3.10 新版功能.

   wchar_t *check_hash_pycs_mode

      控制基于哈希值的 ".pyc" 文件的验证行为: "--check-hash-based-
      pycs" 命令行选项的值。

      有效的值：

      * "L"always"": 无论 'check_source' 旗标的值是什么都会对源文件进
        行哈希验证。

      * "L"never"": 假定基于哈希值的 pyc 始终是有效的。

      * "L"default"": 基于哈希值的 pyc 中的 'check_source' 旗标确定是
        否验证无效。

      默认值： "L"default""。

      参见 **PEP 552** "Deterministic pycs"。

   int configure_c_stdio

      如为非零值，则配置 C 标准流:

      * 在 Windows 中，在 stdin, stdout 和 stderr 上设置二进制模式
        ("O_BINARY")。

      * 如果 "buffered_stdio" 等于零，则禁用 stdin, stdout 和 stderr
        流的缓冲。

      * 如果 "interactive" 为非零值，则启用 stdin 和 stdout 上的流缓冲
        （Windows 中仅限 stdout）。

      默认值: 在 Python 配置中为 "1"，在隔离配置中为 "0"。

   int dev_mode

      如果为非零值，则启用 Python 开发模式。

      默认值: 在 Python 模式中为 "-1"，在隔离模式中为 "0"。

   int dump_refs

      转储 Python 引用？

      如果为非零值，则转储所有在退出时仍存活的对象。

      由 "PYTHONDUMPREFS" 环境变量设置为 "1"。

      需要定义了 "Py_TRACE_REFS" 宏的特殊 Python 编译版：参见
      "configure --with-trace-refs 选项"。

      默认值: "0".

   wchar_t *exec_prefix

      安装依赖于平台的 Python 文件的站点专属目录前缀:
      "sys.exec_prefix"。

      默认值: "NULL".

      Python 路径配置 的一部分。

   wchar_t *executable

      Python 解释器可执行二进制文件的绝对路径: "sys.executable"。

      默认值: "NULL".

      Python 路径配置 的一部分。

   int faulthandler

      启用 faulthandler？

      如果为非零值，则在启动时调用 "faulthandler.enable()"。

      通过 "-X faulthandler" 和 "PYTHONFAULTHANDLER" 环境变量设为 "1"
      。

      默认值: 在 Python 模式中为 "-1"，在隔离模式中为 "0"。

   wchar_t *filesystem_encoding

      *文件系统编码格式*: "sys.getfilesystemencoding()"。

      在 macOS, Android 和 VxWorks 上：默认使用 ""utf-8""。

      在 Windows 上：默认使用 ""utf-8""，或者如果 "PyPreConfig" 的
      "legacy_windows_fs_encoding" 为非零值则使用 ""mbcs""。

      在其他平台上的默认编码格式：

      * 如果 "PyPreConfig.utf8_mode" 为非零值则使用 ""utf-8""。

      * 如果 Python 检测到 "nl_langinfo(CODESET)" 声明为 ASCII 编码格
        式，而 "mbstowcs()" 是从其他的编码格式解码（通常为 Latin1）则
        使用 ""ascii""。

      * 如果 "nl_langinfo(CODESET)" 返回空字符串则使用 ""utf-8""。

      * 在其他情况下，使用 *locale encoding*: "nl_langinfo(CODESET)"
        的结果。

      在 Python 启动时，编码格式名称会规范化为 Python 编解码器名称。
      例如，""ANSI_X3.4-1968"" 将被替换为 ""ascii""。

      参见 "filesystem_errors" 的成员。

   wchar_t *filesystem_errors

      *文件系统错误处理器*: "sys.getfilesystemencodeerrors()"。

      在 Windows 上：默认使用 ""surrogatepass""，或者如果
      "PyPreConfig" 的  "legacy_windows_fs_encoding" 为非零值则使用
      ""replace""。

      在其他平台上：默认使用 ""surrogateescape""。

      支持的错误处理器：

      * ""strict""

      * ""surrogateescape""

      * ""surrogatepass"" (仅支持 UTF-8 编码格式)

      参见 "filesystem_encoding" 的成员。

   unsigned long hash_seed

   int use_hash_seed

      随机化的哈希函数种子。

      如果 "use_hash_seed" 为零，则在 Python 启动时随机选择一个种子，
      并忽略 "hash_seed"。

      由 "PYTHONHASHSEED" 环境变量设置。

      默认的 *use_hash_seed* 值：在 Python 模式下为 "-1"，在隔离模式下
      为 "0"。

   wchar_t *home

      Python 主目录。

      如果 "Py_SetPythonHome()" 已被调用，则当其参数不为 "NULL" 时将使
      用它。

      由 "PYTHONHOME" 环境变量设置。

      默认值: "NULL".

      Python 路径配置 输入的一部分。

   int import_time

      如为非零值，则对导入时间执行性能分析。

      通过 "-X importtime" 选项和 "PYTHONPROFILEIMPORTTIME" 环境变量设
      置为 "1"。

      默认值: "0".

   int inspect

      在执行脚本或命令之后进入交互模式。

      If greater than 0, enable inspect: when a script is passed as
      first argument or the -c option is used, enter interactive mode
      after executing the script or the command, even when "sys.stdin"
      does not appear to be a terminal.

      通过 "-i" 命令行选项执行递增。 如果 "PYTHONINSPECT" 环境变量为非
      空值则设为 "1"。

      默认值: "0".

   int install_signal_handlers

      安装 Python 信号处理器？

      默认值：在 Python 模式下为 "1"，在隔离模式下为 "0"。

   int interactive

      If greater than 0, enable the interactive mode (REPL).

      由 "-i" 命令行选项执行递增。

      默认值: "0".

   int isolated

      If greater than 0, enable isolated mode:

      * "sys.path" contains neither the script's directory (computed
        from "argv[0]" or the current directory) nor the user's site-
        packages directory.

      * Python REPL 将不导入 "readline" 也不在交互提示符中启用默认的
        readline 配置。

      * Set "use_environment" and "user_site_directory" to 0.

      默认值: 在 Python 模式中为 "0"，在隔离模式中为 "1"。

      另请参见 "PyPreConfig.isolated" 。

   int legacy_windows_stdio

      If non-zero, use "io.FileIO" instead of "io.WindowsConsoleIO"
      for "sys.stdin", "sys.stdout" and "sys.stderr".

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

      仅在 Windows 上可用。 "#ifdef MS_WINDOWS" 宏可被用于 Windows 专
      属的代码。

      默认值: "0".

      另请参阅 **PEP 528** (将 Windows 控制台编码格式更改为 UTF-8)。

   int malloc_stats

      如为非零值，则在退出时转储 Python pymalloc 内存分配器 的统计数据
      。

      由 "PYTHONMALLOCSTATS" 环境变量设置为 "1"。

      如果 Python 是 "使用 --without-pymalloc 选项进行配置" 则该选项将
      被忽略。

      默认值: "0".

   wchar_t *platlibdir

      平台库目录名称: "sys.platlibdir"。

      由 "PYTHONPLATLIBDIR" 环境变量设置。

      Default: value of the "PLATLIBDIR" macro which is set by the
      "configure --with-platlibdir option" (default: ""lib"").

      Python 路径配置 输入的一部分。

      3.9 新版功能.

   wchar_t *pythonpath_env

      Module search paths ("sys.path") as a string separated by
      "DELIM" ("os.path.pathsep").

      由 "PYTHONPATH" 环境变量设置。

      默认值: "NULL".

      Python 路径配置 输入的一部分。

   PyWideStringList module_search_paths

   int module_search_paths_set

      模块搜索路径: "sys.path"。

      If "module_search_paths_set" is equal to 0, the function
      calculating the Python Path Configuration overrides the
      "module_search_paths" and sets "module_search_paths_set" to "1".

      默认值：空列表 ("module_search_paths") 和 "0"
      ("module_search_paths_set")。

      Python 路径配置 的一部分。

   int optimization_level

      编译优化级别：

      * "0": Peephole 优化器，将 "__debug__" 设为 "True"。

      * "1": 0 级，移除断言，将 "__debug__" 设为 "False"。

      * "2": 1 级，去除文档字符串。

      通过 "-O" 命令行选项递增。 设置为 "PYTHONOPTIMIZE" 环境变量值。

      默认值: "0".

   PyWideStringList orig_argv

      传给 Python 可执行程序的原始命令行参数列表: "sys.orig_argv"。

      如果 "orig_argv" 列表为空并且 "argv" 不是一个只包含空字符串的列
      表，"PyConfig_Read()" 将在修改 "argv" 之前把 "argv" 拷贝至
      "orig_argv" (如果 "parse_argv" 不为空)。

      另请参阅 "argv" 成员和 "Py_GetArgcArgv()" 函数。

      默认值：空列表。

      3.10 新版功能.

   int parse_argv

      解析命令行参数？

      如果等于 "1"，则以与常规 Python 解析 命令行参数 相同的方式解析
      "argv"，并从 "argv" 中剥离 Python 参数。

      "PyConfig_Read()" 函数只解析 "PyConfig.argv" 参数一次：在参数解
      析完成后，"PyConfig.parse_argv" 将被设为 "2"。 由于 Python 参数
      是从 "PyConfig.argv" 中剥离的，因此解析参数两次会将应用程序选项
      解析为 Python 选项。

      默认值：在 Python 模式下为 "1"，在隔离模式下为 "0"。

      在 3.10 版更改: 现在只有当 "PyConfig.parse_argv" 等于 "1" 时才会
      解析 "PyConfig.argv" 参数。

   int parser_debug

      Parser debug mode. If greater than 0, turn on parser debugging
      output (for expert only, depending on compilation options).

      通过 "-d" 命令行选项递增。 设置为 "PYTHONDEBUG" 环境变量值。

      默认值: "0".

   int pathconfig_warnings

      On Unix, if non-zero, calculating the Python Path Configuration
      can log warnings into "stderr". If equals to 0, suppress these
      warnings.

      It has no effect on Windows.

      默认值：在 Python 模式下为 "1"，在隔离模式下为 "0"。

      Python 路径配置 输入的一部分。

   wchar_t *prefix

      安装依赖于平台的 Python 文件的站点专属目录前缀: "sys.prefix"。

      默认值: "NULL".

      Python 路径配置 的一部分。

   wchar_t *program_name

      用于初始化 "executable" 和在 Python 初始化期间早期错误消息中使用
      的程序名称。

      * 如果 "Py_SetProgramName()" 已被调用，将使用其参数。

      * 在 macOS 上，如果设置了 "PYTHONEXECUTABLE" 环境变量则会使用它
        。

      * 如果定义了 "WITH_NEXT_FRAMEWORK" 宏，当设置了
        "__PYVENV_LAUNCHER__" 环境变量时将会使用它。

      * 如果 "argv" 的 "argv[0]" 可用并且不为空值则会使用它。

      * 否则，在 Windows 上将使用 "L"python""，在其他平台上将使用
        "L"python3""。

      默认值: "NULL".

      Python 路径配置 输入的一部分。

   wchar_t *pycache_prefix

      缓存 ".pyc" 文件被写入到的目录: "sys.pycache_prefix"。

      通过 "-X pycache_prefix=PATH" 命令行选项和 "PYTHONPYCACHEPREFIX"
      环境变量设置。

      如果为 "NULL"，则 "sys.pycache_prefix" 将被设为 "None"。

      默认值: "NULL".

   int quiet

      Quiet mode. If greater than 0, don't display the copyright and
      version at Python startup in interactive mode.

      由 "-q" 命令行选项执行递增。

      默认值: "0".

   wchar_t *run_command

      "-c" 命令行选项的值。

      由 "Py_RunMain()" 使用。

      默认值: "NULL".

   wchar_t *run_filename

      Filename passed on the command line: trailing command line
      argument without "-c" or "-m".

      For example, it is set to "script.py" by the "python3 script.py
      arg" command.

      由 "Py_RunMain()" 使用。

      默认值: "NULL".

   wchar_t *run_module

      "-m" 命令行选项的值。

      由 "Py_RunMain()" 使用。

      默认值: "NULL".

   int show_ref_count

      在退出时显示引用总数？

      Set to 1 by "-X showrefcount" command line option.

      需要 Python 调试编译版 (必须定义 "Py_REF_DEBUG" 宏)。

      默认值: "0".

   int site_import

      在启动时导入 "site" 模块？

      如果等于零，则禁用模块站点的导入以及由此产生的与站点相关的
      "sys.path" 操作。

      如果以后显式地导入 "site" 模块也要禁用这些操作（如果你希望触发这
      些操作，请调用 "site.main()" 函数）。

      通过 "-S" 命令行选项设置为 "0"。

      "sys.flags.no_site" is set to the inverted value of
      "site_import".

      默认值: "1".

   int skip_source_first_line

      如为非零值，则跳过 "PyConfig.run_filename" 源的第一行。

      它将允许使用非 Unix 形式的 "#!cmd"。 这是针对 DOS 专属的破解操作
      。

      通过 "-x" 命令行选项设置为 "1"。

      默认值: "0".

   wchar_t *stdio_encoding

   wchar_t *stdio_errors

      "sys.stdin"、"sys.stdout" 和 "sys.stderr" 的编码格式和编码格式错
      误（但 "sys.stderr" 将始终使用 ""backslashreplace"" 错误处理器）
      。

      如果 "Py_SetStandardStreamEncoding()" 已被调用，则当其 *error*
      和 *errors* 参数不为 "NULL" 时将使用它们。

      如果 "PYTHONIOENCODING" 环境变量非空则会使用它。

      默认编码格式：

      * 如果 "PyPreConfig.utf8_mode" 为非零值则使用 ""UTF-8""。

      * 在其他情况下，使用 *locale encoding*。

      默认错误处理器：

      * 在 Windows 上：使用 ""surrogateescape""。

      * 如果 "PyPreConfig.utf8_mode" 为非零值，或者如果 LC_CTYPE 语言
        区域为 "C" 或 "POSIX" 则使用 ""surrogateescape""。

      * 在其他情况下则使用 ""strict""。

   int tracemalloc

      启用 tracemalloc？

      如果为非零值，则在启动时调用 "tracemalloc.start()"。

      通过 "-X tracemalloc=N" 命令行选项和 "PYTHONTRACEMALLOC" 环境变
      量设置。

      默认值: 在 Python 模式中为 "-1"，在隔离模式中为 "0"。

   int use_environment

      使用 环境变量？

      如果等于零，则忽略 环境变量。

      默认值: 在 Python 配置中为 "1" 而在隔离配置中为 "0"。

   int user_site_directory

      如果为非零值，则将用户站点目录添加到 "sys.path"。

      通过 "-s" 和 "-I" 命令行选项设置为 "0"。

      由 "PYTHONNOUSERSITE" 环境变量设置为 "0"。

      默认值：在 Python 模式下为 "1"，在隔离模式下为 "0"。

   int verbose

      Verbose mode. If greater than 0, print a message each time a
      module is imported, showing the place (filename or built-in
      module) from which it is loaded.

      If greater or equal to 2, print a message for each file that is
      checked for when searching for a module. Also provides
      information on module cleanup at exit.

      由 "-v" 命令行选项执行递增。

      Set to the "PYTHONVERBOSE" environment variable value.

      默认值: "0".

   PyWideStringList warnoptions

      "warnings" 模块用于构建警告过滤器的选项，优先级从低到高:
      "sys.warnoptions"。

      "warnings" 模块以相反的顺序添加 "sys.warnoptions": 最后一个
      "PyConfig.warnoptions" 条目将成为 "warnings.filters" 的第一个条
      目并将最先被检查（最高优先级）。

      "-W" 命令行选项会将其值添加到 "warnoptions" 中，它可以被多次使用
      。

      "PYTHONWARNINGS" 环境变量也可被用于添加警告选项。 可以指定多个选
      项，并以逗号 (",") 分隔。

      默认值：空列表。

   int write_bytecode

      If equal to 0, Python won't try to write ".pyc" files on the
      import of source modules.

      通过 "-B" 命令行选项和 "PYTHONDONTWRITEBYTECODE" 环境变量设置为
      "0"。

      "sys.dont_write_bytecode" 会被初始化为 "write_bytecode" 取反后的
      值。

      默认值: "1".

   PyWideStringList xoptions

      "-X" 命令行选项的值: "sys._xoptions"。

      默认值：空列表。

如果 "parse_argv" 为非零值，则 "argv" 参数将以与常规 Python 解析 命令
行参数 相同的方式被解析，并从 "argv" 中剥离 Python 参数。

"xoptions" 选项将会被解析以设置其他选项：参见 "-X" 命令行选项。

在 3.9 版更改: "show_alloc_count" 字段已被移除。


使用 PyConfig 初始化
====================

用于初始化 Python 的函数：

PyStatus Py_InitializeFromConfig(const PyConfig *config)

   根据 *config* 配置来初始化 Python。

调用方要负责使用 "PyStatus_Exception()" 和 "Py_ExitStatusException()"
来处理异常（错误或退出）。

如果使用了 "PyImport_FrozenModules()"、"PyImport_AppendInittab()" 或
"PyImport_ExtendInittab()"，则必须在 Python 预初始化之后、Python 初始
化之前设置或调用它们。 如果 Python 被多次初始化，则必须在每次初始化
Python 之前调用 "PyImport_AppendInittab()" 或
"PyImport_ExtendInittab()"。

当前的配置 ("PyConfig" 类型) 保存在 "PyInterpreterState.config" 中。

设置程序名称的示例:

   void init_python(void)
   {
       PyStatus status;

       PyConfig config;
       PyConfig_InitPythonConfig(&config);

       /* Set the program name. Implicitly preinitialize Python. */
       status = PyConfig_SetString(&config, &config.program_name,
                                   L"/path/to/my_program");
       if (PyStatus_Exception(status)) {
           goto exception;
       }

       status = Py_InitializeFromConfig(&config);
       if (PyStatus_Exception(status)) {
           goto exception;
       }
       PyConfig_Clear(&config);
       return;

   exception:
       PyConfig_Clear(&config);
       Py_ExitStatusException(status);
   }

More complete example modifying the default configuration, read the
configuration, and then override some parameters:

   PyStatus init_python(const char *program_name)
   {
       PyStatus status;

       PyConfig config;
       PyConfig_InitPythonConfig(&config);

       /* Set the program name before reading the configuration
          (decode byte string from the locale encoding).

          Implicitly preinitialize Python. */
       status = PyConfig_SetBytesString(&config, &config.program_name,
                                        program_name);
       if (PyStatus_Exception(status)) {
           goto done;
       }

       /* Read all configuration at once */
       status = PyConfig_Read(&config);
       if (PyStatus_Exception(status)) {
           goto done;
       }

       /* Append our custom search path to sys.path */
       status = PyWideStringList_Append(&config.module_search_paths,
                                        L"/path/to/more/modules");
       if (PyStatus_Exception(status)) {
           goto done;
       }

       /* Override executable computed by PyConfig_Read() */
       status = PyConfig_SetString(&config, &config.executable,
                                   L"/path/to/my_executable");
       if (PyStatus_Exception(status)) {
           goto done;
       }

       status = Py_InitializeFromConfig(&config);

   done:
       PyConfig_Clear(&config);
       return status;
   }


隔离配置
========

"PyPreConfig_InitIsolatedConfig()" 和 "PyConfig_InitIsolatedConfig()"
函数会创建一个配置来将 Python 与系统隔离开来。 例如，将 Python 嵌入到
某个应用程序。

该配置将忽略全局配置变量、环境变量、命令行参数 ("PyConfig.argv" 将不会
被解析) 和用户站点目录。 C 标准流 (例如 "stdout") 和 LC_CTYPE 语言区域
将保持不变。 信号处理器将不会被安装。

Configuration files are still used with this configuration. Set the
Python Path Configuration ("output fields") to ignore these
configuration files and avoid the function computing the default path
configuration.


Python 配置
===========

"PyPreConfig_InitPythonConfig()" 和 "PyConfig_InitPythonConfig()" 函数
会创建一个配置来构建一个行为与常规 Python 相同的自定义 Python。

环境变量和命令行参数将被用于配置 Python，而全局配置变量将被忽略。

此函数将根据 LC_CTYPE 语言区域、"PYTHONUTF8" 和 "PYTHONCOERCECLOCALE"
环境变量启用 C 语言区域强制转换 (**PEP 538**) 和 Python UTF-8 模式
(**PEP 540**)。


Python 路径配置
===============

"PyConfig" 包含多个用于路径配置的字段：

* 路径配置输入：

  * "PyConfig.home"

  * "PyConfig.platlibdir"

  * "PyConfig.pathconfig_warnings"

  * "PyConfig.program_name"

  * "PyConfig.pythonpath_env"

  * 当前工作目录：用于获取绝对路径

  * "PATH" 环境变量用于获取程序的完整路径 (来自
    "PyConfig.program_name")

  * "__PYVENV_LAUNCHER__" 环境变量

  * （仅限 Windows only） 注册表 HKEY_CURRENT_USER 和
    HKEY_LOCAL_MACHINE 的 "SoftwarePythonPythonCoreX.YPythonPath" 项下
    的应用程序目录（其中 X.Y 为 Python 版本）。

* 路径配置输出字段：

  * "PyConfig.base_exec_prefix"

  * "PyConfig.base_executable"

  * "PyConfig.base_prefix"

  * "PyConfig.exec_prefix"

  * "PyConfig.executable"

  * "PyConfig.module_search_paths_set", "PyConfig.module_search_paths"

  * "PyConfig.prefix"

If at least one "output field" is not set, Python calculates the path
configuration to fill unset fields. If "module_search_paths_set" is
equal to 0, "module_search_paths" is overridden and
"module_search_paths_set" is set to 1.

It is possible to completely ignore the function calculating the
default path configuration by setting explicitly all path
configuration output fields listed above. A string is considered as
set even if it is non-empty. "module_search_paths" is considered as
set if "module_search_paths_set" is set to 1. In this case, path
configuration input fields are ignored as well.

Set "pathconfig_warnings" to 0 to suppress warnings when calculating
the path configuration (Unix only, Windows does not log any warning).

如果 "base_prefix" 或 "base_exec_prefix" 字段未设置，它们将分别从
"prefix" 和 "exec_prefix" 继承其值。

"Py_RunMain()" 和 "Py_Main()" 将修改 "sys.path":

* 如果 "run_filename" 已设置并且是一个包含 "__main__.py" 脚本的目录，
  则会将 "run_filename" 添加到 "sys.path" 的开头。

* 如果 "isolated" 为零：

  * 如果设置了 "run_module"，则将当前目录添加到 "sys.path" 的开头。 如
    果无法读取当前目录则不执行任何操作。

  * 如果设置了 "run_filename"，则将文件名的目录添加到 "sys.path" 的开
    头。

  * 在其他情况下，则将一个空字符串添加到 "sys.path" 的开头。

如果 "site_import" 为非零值，则 "sys.path" 可通过 "site" 模块修改。 如
果 "user_site_directory" 为非零值且用户的 site-package 目录存在，则
"site" 模块会将用户的 site-package 目录附加到 "sys.path"。

路径配置会使用以下配置文件：

* "pyvenv.cfg"

* "python._pth" (仅Windows)

* "pybuilddir.txt" (仅Unix)

"__PYVENV_LAUNCHER__" 环境变量将被用于设置 "PyConfig.base_executable"


Py_RunMain()
============

int Py_RunMain(void)

   执行在命令行或配置中指定的命令 ("PyConfig.run_command")、脚本
   ("PyConfig.run_filename") 或模块 ("PyConfig.run_module")。

   在默认情况下如果使用了 "-i" 选项，则运行 REPL。

   最后，终结化 Python 并返回一个可传递给 "exit()" 函数的退出状态。

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


Py_GetArgcArgv()
================

void Py_GetArgcArgv(int *argc, wchar_t ***argv)

   在 Python 修改原始命令行参数之前，获取这些参数。

   另请参阅 "PyConfig.orig_argv" 成员。


多阶段初始化私有暂定 API
========================

本节介绍的私有暂定 API 引入了多阶段初始化，它是 **PEP 432** 的核心特性
：

* “核心”初始化阶段，“最小化的基本 Python”：

  * 内置类型；

  * 内置异常；

  * 内置和已冻结模块；

  * "sys" 模块仅部分初始化（例如: "sys.path" 尚不存在）。

* "主要"初始化阶段，Python 被完全初始化：

  * 安装并配置 "importlib"；

  * 应用 路径配置；

  * 安装信号处理器；

  * 完成 "sys" 模块初始化 (例如：创建 "sys.stdout" 和 "sys.path")；

  * 启用 "faulthandler" 和 "tracemalloc" 等可选功能；

  * 导入 "site" 模块；

  * 等等.

私有临时API：

* "PyConfig._init_main": if set to 0, "Py_InitializeFromConfig()"
  stops at the "Core" initialization phase.

* "PyConfig._isolated_interpreter": if non-zero, disallow threads,
  subprocesses and fork.

PyStatus _Py_InitializeMain(void)

   进入“主要”初始化阶段，完成 Python 初始化。

在“核心”阶段不会导入任何模块，也不会配置 "importlib" 模块: 路径配置 只
会在“主要”阶段期间应用。 这可能允许在 Python 中定制 Python 以覆盖或微
调 路径配置，也可能会安装自定义的 "sys.meta_path" 导入器或导入钩子等等
。

It may become possible to calculatin the Path Configuration in Python,
after the Core phase and before the Main phase, which is one of the
**PEP 432** motivation.

“核心”阶段并没有完整的定义：在这一阶段什么应该可用什么不应该可用都尚未
被指明。 该 API 被标记为私有和暂定的：也就是说该 API 可以随时被修改甚
至被移除直到设计出适用的公共 API。

在“核心”和“主要”初始化阶段之间运行 Python 代码的示例:

   void init_python(void)
   {
       PyStatus status;

       PyConfig config;
       PyConfig_InitPythonConfig(&config);
       config._init_main = 0;

       /* ... customize 'config' configuration ... */

       status = Py_InitializeFromConfig(&config);
       PyConfig_Clear(&config);
       if (PyStatus_Exception(status)) {
           Py_ExitStatusException(status);
       }

       /* Use sys.stderr because sys.stdout is only created
          by _Py_InitializeMain() */
       int res = PyRun_SimpleString(
           "import sys; "
           "print('Run Python code before _Py_InitializeMain', "
                  "file=sys.stderr)");
       if (res < 0) {
           exit(1);
       }

       /* ... put more configuration code here ... */

       status = _Py_InitializeMain();
       if (PyStatus_Exception(status)) {
           Py_ExitStatusException(status);
       }
   }
