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 必须大于等于
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_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
将不被支持。默认值:
PYMEM_ALLOCATOR_NOT_SET
。int configure_locale
将 LC_CTYPE 语言区域设为用户选择的语言区域。
如果等于
0
,则将 coerce_c_locale 和 coerce_c_locale_warn 的成员设为0
。参见 locale encoding。
默认值: 在 Python 配置中为
1
,在隔离配置中为0
。int coerce_c_locale
如果等于
2
,强制转换 C 语言区域。如果等于
1
,则读取 LC_CTYPE 语言区域来确定其是否应当被强制转换。参见 locale encoding。
默认值: 在 Python 配置中为
-1
,在隔离配置中为0
。int coerce_c_locale_warn
如为非零值,则会在 C 语言区域被强制转换时发出警告。
默认值: 在 Python 配置中为
-1
,在隔离配置中为0
。int dev_mode
Python 开发模式: 参见 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 模式。
通过 -X utf8 命令行选项和 PYTHONUTF8 环境变量设为
0
或1
。如果
LC_CTYPE
语言区域为C
或POSIX
也会被设为1
。默认值: 在 Python 配置中为
-1
而在隔离配置中为0
。
使用 PyPreConfig 预初始化 Python
Python 的预初始化:
设置 Python 内存分配器 (PyPreConfig.allocator)
配置 LC_CTYPE 语言区域 (locale encoding)
当前的预配置 (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 配置。
已经初始化的字段会保持不变。
调用此函数时不再计算或修改用于 路径配置 的字段,如 Python 3.11 那样。
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
时才会解析参数。在 3.11 版更改: PyConfig_Read() 不会再计算所有路径,因此在 Python 路径配置 下列出的字段可能不会再更新直到 Py_InitializeFromConfig() 被调用。
void PyConfig_Clear(PyConfig *config)
释放配置内存
如有必要大多数 PyConfig
方法将会 预初始化 Python。 在这种情况下,Python 预初始化配置 (PyPreConfig) 将以 PyConfig 为基础。 如果要调整与 PyPreConfig 相同的配置字段,它们必须在调用 PyConfig 方法之前被设置:
此外,如果使用了 PyConfig_SetArgv() 或 PyConfig_SetBytesArgv(),则必须在调用其他方法之前调用该方法,因为预初始化配置取决于命令行参数(如果 parse_argv 为非零值)。
这些方法的调用者要负责使用 PyStatus_Exception()
和 Py_ExitStatusException()
来处理异常(错误或退出)。
结构体字段:
PyWideStringList argv
命令行参数: sys.argv。
将 parse_argv 设为
1
将以与普通 Python 解析 Python 命令行参数相同的方式解析 argv 再从 argv 中剥离 Python 参数。如果 argv 为空,则会添加一个空字符串以确保 sys.argv 始终存在并且永远不为空。
默认值:
NULL
.另请参阅 orig_argv 成员。
int safe_path
如果等于零,
Py_RunMain()
会在启动时向 sys.path 开头添加一个可能不安全的路径:如果 argv[0] 等于
L"-m"
(python -m module
),则添加当前工作目录。如果是运行脚本 (
python script.py
),则添加脚本的目录。 如果是符号链接,则会解析符号链接。在其他情况下 (
python -c code
和python
),将添加一个空字符串,这表示当前工作目录。
通过 -P 命令行选项和 PYTHONSAFEPATH 环境变量设置为
1
。默认值:Python 配置中为
0
,隔离配置中为1
。3.11 新版功能.
wchar_t *base_exec_prefix
默认值:
NULL
.Python 路径配置 的一部分。
wchar_t *base_executable
Python 基础可执行文件:
sys._base_executable
。由
__PYVENV_LAUNCHER__
环境变量设置。如为
NULL
则从 PyConfig.executable 设置。默认值:
NULL
.Python 路径配置 的一部分。
wchar_t *base_prefix
默认值:
NULL
.Python 路径配置 的一部分。
int buffered_stdio
如果等于
0
且 configure_c_stdio 为非零值,则禁用 C 数据流 stdout 和 stderr 的缓冲。通过 -u 命令行选项和 PYTHONUNBUFFERED 环境变量设置为
0
。stdin 始终以缓冲模式打开。
默认值:
1
.int bytes_warning
如果等于
1
,则在将 bytes 或 bytearray 与 str 进行比较,或将 bytes 与 int 进行比较时发出警告。如果大于等于
2
,则在这些情况下引发 BytesWarning 异常。由 -b 命令行选项执行递增。
默认值:
0
.int warn_default_encoding
如为非零值,则在 io.TextIOWrapper 使用默认编码格式时发出 EncodingWarning 警告。 详情请参阅 选择性的 EncodingWarning。
默认值:
0
.3.10 新版功能.
int code_debug_ranges
如果等于
0
,则禁用在代码对象中包括末尾行和列映射。 并且禁用在特定错误位置打印回溯标记。通过 PYTHONNODEBUGRANGES 环境变量和 -X no_debug_ranges 命令行选项设置为
0
。默认值:
1
.3.11 新版功能.
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 开发模式。
通过 -X dev 选项和 PYTHONDEVMODE 环境变量设置为
1
。默认值: 在 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
在执行脚本或命令之后进入交互模式。
如果大于
0
,则启用检查:当脚本作为第一个参数传入或使用了 -c 选项时,在执行脚本或命令后进入交互模式,即使在 sys.stdin 看来并非一个终端时也是如此。通过 -i 命令行选项执行递增。 如果 PYTHONINSPECT 环境变量为非空值则设为
1
。默认值:
0
.int install_signal_handlers
安装 Python 信号处理句柄?
默认值:在 Python 模式下为
1
,在隔离模式下为0
。int interactive
如果大于
0
,则启用交互模式(REPL)。由 -i 命令行选项执行递增。
默认值:
0
.int int_max_str_digits
配置 整数字符串转换长度限制。 初始值为
-1
表示该值将从命令行或环境获取否则默认为 4300 (sys.int_info.default_max_str_digits)。 值为0
表示禁用限制。 大于 0 但小于 640 (sys.int_info.str_digits_check_threshold) 的值将不被支持并会产生错误。通过 -X int_max_str_digits 命令行旗标或 PYTHONINTMAXSTRDIGITS 环境变量配置。
默认值:在 Python 模式下为
-1
。 在孤立模式下为 4300 (sys.int_info.default_max_str_digits)。3.12 新版功能.
int isolated
如果大于
0
,则启用隔离模式:将 safe_path 设为
1
: 在 Python 启动时将不在 sys.path 前添加有潜在不安全性的路径,如当前目录、脚本所在目录或空字符串。将 use_environment 设为
0
: 忽略PYTHON
环境变量。将 user_site_directory 设为
0
: 不要将用户级站点目录添加到 sys.path。Python REPL 将不导入 readline 也不在交互提示符中启用默认的 readline 配置。
通过 -I 命令行选项设置为
1
。默认值: 在 Python 模式中为
0
,在隔离模式中为1
。另请参阅 隔离配置 和 PyPreConfig.isolated。
int legacy_windows_stdio
如为非零值,则使用 io.FileIO 代替
io._WindowsConsoleIO
作为 sys.stdin、sys.stdout 和 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 环境变量设置。
默认值:由 configure —with-platlibdir 选项 设置的
PLATLIBDIR
宏的值 (默认值:"lib"
,在 Windows 上则为"DLLs"
)。Python 路径配置 输入的一部分。
3.9 新版功能.
在 3.11 版更改: 目前在 Windows 系统中该宏被用于定位标准库扩展模块,通常位于
DLLs
下。 不过,出于兼容性考虑,请注意在任何非标准布局包括树内构建和虚拟环境中,该值都将被忽略。wchar_t *pythonpath_env
模块搜索路径 (sys.path) 为一个用
DELIM
(os.pathsep) 分隔的字符串。由 PYTHONPATH 环境变量设置。
默认值:
NULL
.Python 路径配置 输入的一部分。
PyWideStringList module_search_paths
int module_search_paths_set
模块搜索路径: sys.path。
如果 module_search_paths_set 等于
0
,Py_InitializeFromConfig() 将替代 module_search_paths 并将 module_search_paths_set 设为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
解析器调试模式。 如果大于
0
,则打开解析器调试输出(仅针对专家,取决于编译选项)。通过 -d 命令行选项递增。 设置为 PYTHONDEBUG 环境变量值。
需要 Python 调试编译版 (必须定义
Py_DEBUG
宏)。默认值:
0
.int pathconfig_warnings
如为非零值,则允许计算路径配置以将警告记录到
stderr
中。 如果等于0
,则抑制这些警告。默认值:在 Python 模式下为
1
,在隔离模式下为0
。Python 路径配置 输入的一部分。
在 3.11 版更改: 现在也适用于 Windows。
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
安静模式。 如果大于
0
,则在交互模式下启动 Python 时不显示版权和版本。由 -q 命令行选项执行递增。
默认值:
0
.wchar_t *run_command
-c 命令行选项的值。
由 Py_RunMain() 使用。
默认值:
NULL
.wchar_t *run_filename
通过命令行传入的文件名:不包含 -c 或 -m 的附加命令行参数。 它会被 Py_RunMain() 函数使用。
例如,对于命令行
python3 script.py arg
它将被设为script.py
。另请参阅 PyConfig.skip_source_first_line 选项。
默认值:
NULL
.wchar_t *run_module
-m 命令行选项的值。
由 Py_RunMain() 使用。
默认值:
NULL
.int show_ref_count
在退出时显示总引用计数(不包括永生对象)?
通过 -X showrefcount 命令行选项设置为
1
。需要 Python 调试编译版 (必须定义
Py_REF_DEBUG
宏)。默认值:
0
.int site_import
在启动时导入 site 模块?
如果等于零,则禁用模块站点的导入以及由此产生的与站点相关的 sys.path 操作。
如果以后显式地导入 site 模块也要禁用这些操作(如果你希望触发这些操作,请调用 site.main() 函数)。
通过 -S 命令行选项设置为
0
。sys.flags.no_site 会被设为 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 perf_profiling
启用与 perf 性能分析器兼容的模式?
如果为非零值,则初始化 perf trampoline。 更多信息参见 Python 对 Linux perf 性能分析器的支持。
通过 -X perf 命令行选项和 PYTHONPERFSUPPORT 环境变量设置。
默认值:
-1
。3.12 新版功能.
int use_environment
使用 环境变量?
如果等于零,则忽略 环境变量。
由 -E 环境变量设置为
0
。默认值: 在 Python 配置中为
1
而在隔离配置中为0
。int user_site_directory
如果为非零值,则将用户站点目录添加到 sys.path。
由 PYTHONNOUSERSITE 环境变量设置为
0
。默认值:在 Python 模式下为
1
,在隔离模式下为0
。int verbose
详细模式。 如果大于
0
,则每次导入模块时都会打印一条消息,显示加载模块的位置(文件名或内置模块)。如果大于等于
2
,则为搜索模块时每个被检查的文件打印一条消息。 还在退出时提供关于模块清理的信息。由 -v 命令行选项执行递增。
通过 PYTHONVERBOSE 环境变量值设置。
默认值:
0
.PyWideStringList warnoptions
warnings 模块用于构建警告过滤器的选项,优先级从低到高: sys.warnoptions。
warnings 模块以相反的顺序添加 sys.warnoptions: 最后一个 PyConfig.warnoptions 条目将成为
warnings.filters
的第一个条目并将最先被检查(最高优先级)。-W 命令行选项会将其值添加到 warnoptions 中,它可以被多次使用。
PYTHONWARNINGS 环境变量也可被用于添加警告选项。 可以指定多个选项,并以逗号 (
,
) 分隔。默认值:空列表。
int write_bytecode
如果等于
0
,Python 将不会尝试在导入源模块时写入.pyc
文件。通过 -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);
}
更完整的示例会修改默认配置,读取配置,然后覆盖某些参数。 请注意自 3.11 版开始,许多参数在初始化之前不会被计算,因此无法从配置结构体中读取值。在调用初始化之前设置的任何值都将不会被初始化操作改变:
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;
}
/* Specify sys.path explicitly */
/* If you want to modify the default set of paths, finish
initialization first and then use PySys_GetObject("path") */
config.module_search_paths_set = 1;
status = PyWideStringList_Append(&config.module_search_paths,
L"/path/to/stdlib");
if (PyStatus_Exception(status)) {
goto done;
}
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 语言区域将保持不变。 信号处理句柄将不会被安装。
该配置仍然会使用配置文件来确定未被指明的路径。 请确保指定了 PyConfig.home 以避免计算默认的路径配置。
Python 配置
PyPreConfig_InitPythonConfig() 和 PyConfig_InitPythonConfig() 函数会创建一个配置来构建一个行为与常规 Python 相同的自定义 Python。
环境变量和命令行参数将被用于配置 Python,而全局配置变量将被忽略。
此函数将根据 LC_CTYPE 语言区域、PYTHONUTF8 和 PYTHONCOERCECLOCALE 环境变量启用 C 语言区域强制转换 (PEP 538) 和 Python UTF-8 模式 (PEP 540)。
Python 路径配置
PyConfig 包含多个用于路径配置的字段:
路径配置输入:
当前工作目录:用于获取绝对路径
PATH
环境变量用于获取程序的完整路径 (来自 PyConfig.program_name)__PYVENV_LAUNCHER__
环境变量(仅限 Windows only) 注册表 HKEY_CURRENT_USER 和 HKEY_LOCAL_MACHINE 的 “SoftwarePythonPythonCoreX.YPythonPath” 项下的应用程序目录(其中 X.Y 为 Python 版本)。
路径配置输出字段:
如果至少有一个“输出字段”未被设置,Python 就会计算路径配置来填充未设置的字段。 如果 module_search_paths_set 等于 0
,则 module_search_paths 将被覆盖并且 module_search_paths_set 将被设置为 1
。
通过显式地设置上述所有路径配置输出字段可以完全忽略计算默认路径配置的函数。 即使字符串不为空也会被视为已设置。 如果 module_search_paths_set
被设为 1
则 module_search_paths
会被视为已设置。 在这种情况下,module_search_paths
将不加修改地被使用。
将 pathconfig_warnings 设为 0
以便在计算路径配置时抑制警告(仅限 Unix,Windows 不会记录任何警告)。
如果 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
._pth
文件 (例如:python._pth
)pybuilddir.txt
(仅Unix)
如果存在 ._pth
文件:
将 isolated 设为
1
。将 use_environment 设为
0
。将 site_import 设为
0
。将 safe_path 设为
1
。
__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”:
“主要”初始化阶段,Python 被完全初始化:
安装并配置 importlib;
应用 路径配置;
安装信号处理句柄;
完成 sys 模块初始化 (例如:创建 sys.stdout 和 sys.path);
启用 faulthandler 和 tracemalloc 等可选功能;
导入 site 模块;
等等.
私有临时API:
PyConfig._init_main
: 如果设为0
,Py_InitializeFromConfig() 将在“核心”初始化阶段停止。
PyStatus _Py_InitializeMain(void)
进入“主要”初始化阶段,完成 Python 初始化。
在“核心”阶段不会导入任何模块,也不会配置 importlib
模块: 路径配置 只会在“主要”阶段期间应用。 这可能允许在 Python 中定制 Python 以覆盖或微调 路径配置,也可能会安装自定义的 sys.meta_path 导入器或导入钩子等等。
在核心阶段之后主要阶段之前,将有可能在 Python 中计算 路径配置,这是 PEP 432 的动机之一。
“核心”阶段并没有完整的定义:在这一阶段什么应该可用什么不应该可用都尚未被指明。 该 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);
}
}