Python 3.6.10 C源码导入系统:_find_and_load函数及C层机制问询
PyId__find_and_load解析 Hey there! Let's break this down clearly since you're diving deep into Python 3.6.10's C source for module imports.
First: Why You Can't Find PyId__find_and_load as a Function
First off, PyId__find_and_load isn't a C function—it's a method name identifier used internally by Python to avoid repeated string creation. Here's the breakdown:
- It's defined via the
Py_DEFINE_IDmacro, which generates a globalPyUnicodeObject*variable tied to the string"_find_and_load". You might find the macro invocation in files likePython/import.cor related headers (search forPy_DEFINE_IDpaired with_find_and_load). - The actual implementation behind this identifier is a Python function:
importlib._bootstrap._find_and_load, which lives in Python's standard library code (not C source). The C code usesPyId__find_and_loadto quickly look up this Python method without constructing a new string each time.
What That _PyObject_CallMethodIdObjArgs Line Does
The line you're looking at is the C layer handing off the import request to Python's importlib implementation:
mod = _PyObject_CallMethodIdObjArgs(interp->importlib, &PyId__find_and_load, abs_name, interp->import_func, NULL);
Let's unpack each part:
interp->importlib: A pointer to theimportlib._bootstrapmodule object, loaded during interpreter initialization and acting as the core of Python's import system.&PyId__find_and_load: The identifier for the_find_and_loadmethod we just discussed.abs_name: The absolute name of the module being imported (e.g.,"a"or"package.submodule").interp->import_func: A C function pointer that acts as a fallback hook for imports (used for built-in modules).- The
NULLsignals the end of arguments.
This call returns the loaded module object (stored in mod) or NULL if an error occurs (with an exception set).
C-Level Flow of Python's Import System (3.6.10)
Here's the high-level sequence when you run import a:
- Top-Level Trigger: The Python bytecode for
import acalls into the C functionPyImport_ImportModuleLevelObject(inPython/import.c). - Initial Checks: This function validates the import request, checks if the module is already loaded in
sys.modules, and prepares to load it if not. - Hand Off to Importlib: Eventually, the code reaches the line you found, which calls
importlib._bootstrap._find_and_loadvia the C API. - Python-Layer Heavy Lifting: The
_find_and_loadPython function handles the core import logic:- Calls
_find_specto locate the module (checkssys.path, built-in modules, etc.). - Creates a module object from the spec.
- Loads the module's code (from a .py file, bytecode, or built-in extension).
- Runs the module's code to initialize variables, functions, and classes.
- Calls
- Return to C Layer: The loaded module object is passed back to the C code, which adds it to
sys.modulesand returns it to the Python runtime.
Key point: Since Python 3.3, most of the import logic lives in Python code (importlib) rather than C. The C layer acts as a thin wrapper that bridges the interpreter's core to the flexible, Python-based import system.
内容的提问来源于stack exchange,提问作者Espada

