The Python/C API, 发布 3.8.5
1.6 嵌入 Python
The one important task that only embedders (as opposed to extension writers) of the Python interpreter have to worry
about is the initialization, and possibly the finalization, of the Python interpreter. Most functionality of the interpreter
can only be used after the interpreter has been initialized.
The basic initialization function is Py_Initialize(). This initializes the table of loaded modules, and creates the
fundamental modules builtins, __main__, and sys. It also initializes the module search path (sys.path).
Py_Initialize() does not set the ”script argument list” (sys.argv). If this variable is needed by Python
code that will be executed later, it must be set explicitly with a call to PySys_SetArgvEx(argc, argv,
updatepath) after the call to Py_Initialize().
On most systems (in particular, on Unix and Windows, although the details are slightly different),
Py_Initialize() calculates the module search path based upon its best guess for the location of the standard
Python interpreter executable, assuming that the Python library is found in a fixed location relative to the Python in-
terpreter executable. In particular, it looks for a directory named lib/pythonX.Y relative to the parent directory
where the executable named python is found on the shell command search path (the environment variable PATH).
For instance, if the Python executable is found in /usr/local/bin/python, it will assume that the libraries
are in /usr/local/lib/pythonX.Y. (In fact, this particular path is also the ”fallback” location, used when no
executable file named python is found along PATH.) The user can override this behavior by setting the environment
variable PYTHONHOME, or insert additional directories in front of the standard path by setting PYTHONPATH.
The embedding application can steer the search by calling Py_SetProgramName(file) before calling
Py_Initialize(). Note that PYTHONHOME still overrides this and PYTHONPATH is still inserted in front
of the standard path. An application that requires total control has to provide its own implementation of
Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix(), and Py_GetProgramFullPath() (all
defined in Modules/getpath.c).
Sometimes, it is desirable to ”uninitialize” Python. For instance, the application may want to start over (make
another call to Py_Initialize()) or the application is simply done with its use of Python and wants to
free memory allocated by Python. This can be accomplished by calling Py_FinalizeEx(). The function
Py_IsInitialized() returns true if Python is currently in the initialized state. More information about these
functions is given in a later chapter. Notice that Py_FinalizeEx() does not free all memory allocated by the
Python interpreter, e.g. memory allocated by extension modules currently cannot be released.
1.7 调试构建
Python can be built with several macros to enable extra checks of the interpreter and extension modules. These
checks tend to add a large amount of overhead to the runtime so they are not enabled by default.
A full list of the various types of debugging builds is in the file Misc/SpecialBuilds.txt in the Python source
distribution. Builds are available that support tracing of reference counts, debugging the memory allocator, or low-
level profiling of the main interpreter loop. Only the most frequently-used builds will be described in the remainder
of this section.
Compiling the interpreter with the Py_DEBUG macro defined produces what is generally meant by ”a debug build” of
Python. Py_DEBUG is enabled in the Unix build by adding --with-pydebug to the ./configure command.
It is also implied by the presence of the not-Python-specific _DEBUG macro. When Py_DEBUG is enabled in the
Unix build, compiler optimization is disabled.
除了前面描述的引用计数调试之外,还执行以下额外检查:
• 额外检查将添加到对象分配器。
• 额外的检查将添加到解析器和编译器中。
• Downcasts from wide types to narrow types are checked for loss of information.
• 许多断言被添加到字典和集合实现中。另外,集合对象包含 test_c_api() 方法。
• 添加输入参数的完整性检查到框架创建中。
1.6. 嵌入 Python 11