只有 Python 解释器的嵌入方(相对于扩展编写者而言)才需要担心的一项重要任务是它的初始化,可能还有它的最终化。 解释器的大多数功能只有在解释器被初始化之后才能被使用。
基本的初始化函数是 Py_Initialize()。 此函数将初始化已加载模块表,并创建基本模块 builtins, __main__ 和 sys。 它还将初始化模块搜索路径 (sys.path)。
Py_Initialize() 不会设置 "脚本参数列表" (sys.argv)。 如果稍后将要执行的 Python 代码需要此变量,则要设置 PyConfig.argv 并且还要设置 PyConfig.parse_argv: 参见 Python 初始化配置。
在大多数系统上(特别是 Unix 和 Windows,虽然在细节上有所不同),Py_Initialize() 将根据对标准 Python 解释器可执行文件的位置的最佳猜测来计算模块搜索路径,并设定 Python 库可在相对于 Python 解释器可执行文件的固定位置上找到。 特别地,它将相对于在 shell 命令搜索路径 (环境变量 PATH) 上找到的名为 python 的可执行文件所在父目录中查找名为 lib/pythonX.Y 的目录。
举例来说,如果 Python 可执行文件位于 /usr/local/bin/python,它将假定库位于 /usr/local/lib/pythonX.Y。 (实际上,这个特定路径还将成为“回退”位置,会在当无法在 PATH 中找到名为 python 的可执行文件时被使用。) 用户可以通过设置环境变量 PYTHONHOME,或通过设置 PYTHONPATH 在标准路径之前插入额外的目录来覆盖此行为。
嵌入的应用程序可以通过在调用 Py_Initialize() 之前 调用 Py_SetProgramName(file) 来改变搜索次序。 请注意 PYTHONHOME 仍然会覆盖此设置并且 PYTHONPATH 仍然会被插入到标准路径之前。 需要完全控制权的应用程序必须提供它自己的 Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix() 和 Py_GetProgramFullPath() 实现(这些函数均在 Modules/getpath.c 中定义)。
有时,还需要对 Python 进行“反初始化”。 例如,应用程序可能想要重新启动 (再次调用 Py_Initialize()) 或者应用程序对 Python 的使用已经完成并想要释放 Python 所分配的内存。 这可以通过调用 Py_FinalizeEx() 来实现。 如果当前 Python 处于已初始化状态则 Py_IsInitialized() 函数将返回真值。 有关这些函数的更多信息将在之后的章节中给出。 请注意 Py_FinalizeEx() 不会 释放所有由 Python 解释器所分配的内存,例如由扩展模块所分配的内存目前是不会被释放的。 |