python模块导入通过\_import\_函数执行查找、加载、初始化三阶段:先查sys.modules缓存,再经sys.meta_path和sys.path查找;找到后由loader编译执行;最后设置\_\_name\_\_等属性并完成初始化。

Python 的模块导入不是简单地把文件内容复制进来,而是通过一套严谨的加载流程完成的。核心在于 _import_ 函数(实际由 __import__ 调用,底层由 importlib._bootstrap 实现),它控制从查找、加载到初始化的全过程。
模块查找阶段:sys.meta_path 与 sys.path 的协同作用
当执行 import xxx 时,Python 首先尝试在已缓存的 sys.modules 中查找。若未命中,则依次遍历 sys.meta_path 中的 finder 对象(如 PathFinder)。默认的 PathFinder 会基于 sys.path 中的路径,按顺序拼接 xxx.py、xxx/__init__.py 等路径,检查文件是否存在。
-
sys.meta_path支持自定义 finder,可用于实现 zip 包导入、网络模块加载等扩展行为 -
sys.path中的空字符串代表当前目录,修改它可影响模块搜索顺序(但不推荐直接操作) - 内置模块(如
sys、builtins)由BuiltinImporter直接处理,不走文件系统路径
模块加载阶段:从源码编译到代码对象执行
找到对应文件后,Python 根据后缀选择 loader(如 SourceFileLoader 加载 .py,ExtensionFileLoader 加载 .so/.dll)。loader 负责读取源码、调用 compile() 编译为字节码(PyCodeObject),再通过 exec() 在模块命名空间中运行该代码对象。
启山智软物流配送是基于Spring Cloud 和 Vue.js的JAVA物流配送系统。包含总控制后台 、城市合伙人(商家pc端)、 区域团长后台 、用户端小程序 、手机H5等多个操作模块。为响应用户需求我们新增了后台自定义装修组件模块,使页面更加美观,操作更加灵活简便。淘宝商品CSV一键导入,提升用户使用感。还有与众不同的管理台侧边栏设计,打破传统管理台样式。 另有公众号接龙、引导页上传、区域团
- 每次 import 都只执行一次模块顶层代码;重复 import 直接返回
sys.modules中已缓存的模块对象 -
from xxx import yyy本质仍是完整加载xxx,再从其命名空间提取yyy - 如果模块中有语法错误,会在
exec阶段抛出SyntaxError,而非导入时立即报错
模块初始化阶段:__name__、__package__ 与 __path__ 的设置
执行模块代码前,loader 会预先设置关键属性:__name__ 设为模块全名(如 a.b.c),__package__ 设为父包名(用于相对导入解析),对包目录还会初始化 __path__ 列表(支持后续子模块查找)。
立即学习“Python免费学习笔记(深入)”;
- 顶层脚本的
__name__是'__main__',这正是if __name__ == '__main__':的判断依据 - 相对导入(
from . import xxx)依赖__package__,若模块非包内执行或未正确设置,会触发SystemError或ImportError - 包的
__path__可被动态修改,用于实现 namespace package(PEP 420)
手动触发导入:importlib.import_module 与 __import__ 的区别
显式调用 importlib.import_module('a.b.c') 是推荐方式,它自动处理包层级和相对导入逻辑;而内置 __import__ 行为更底层,对相对导入支持有限,且返回的是最左端模块(import a.b.c 时返回 a 而非 c),日常开发应避免直接使用。
-
importlib.util.spec_from_file_location()+importlib.util.module_from_spec()可实现完全手动控制加载过程,适合插件系统或热重载场景 - 动态导入失败时,异常类型与普通 import 一致(
ModuleNotFoundError、ImportError等),需显式捕获 - 所有导入最终都经由
importlib._bootstrap._find_and_load()统一调度,这是 CPython 的核心实现入口









