Python的import何时将模块加载到内存?为何import django未加载全部模块?
Python模块加载机制相关问题解答
模块的实际加载时机
Python 的 import 机制本身没有默认的懒加载逻辑,模块的加载触发规则是固定的:
- 当你第一次执行对应模块的导入语句(不管是
import 模块名还是from 模块名 import 对象)时,Python 会先检查缓存字典sys.modules中是否存在该模块的实例,不存在才会触发完整加载流程:定位模块文件、编译为字节码、执行模块的所有顶层代码,最终生成的模块对象会存入sys.modules缓存,后续重复导入会直接取缓存对象,不会重复加载。 - 对于包(包含
__init__.py的目录)来说,导入顶层包时只会执行包根目录下__init__.py的顶层代码,不会自动递归导入所有子包、子模块,除非顶层__init__.py中显式写了导入子模块的语句。
为什么 import django 不会加载所有 Django 模块
这是 Django 官方的设计选择,和 Python 本身的导入逻辑无关:
Django 顶层的 __init__.py 中仅做了最基础的初始化操作,比如定义版本号、执行基础运行环境检查、初始化全局配置占位符,并没有导入 django.http、django.db、django.template 等业务功能子模块,所以执行 import django 时,仅会加载这个顶层初始化文件生成的模块对象,内存占用增长极低,很难被观测到。
你测试中观测到的内存上涨,是执行 from django.http import HttpResponse 时才触发的:此时 Python 会先加载 django.http 子包(执行 django/http/__init__.py 的代码),再加载该子包依赖的其他模块,最终导出 HttpResponse 对象,这个过程涉及到多个模块的加载,才会出现明显的内存占用上升。
绝大多数大型 Python 库都会采用这种设计,避免导入顶层包时引入不必要的性能开销和内存占用,你观测到的现象不是 import 关键字自带的懒加载,而是库本身的结构设计导致的。
内容的提问来源于stack exchange,提问作者diviquery
相关产品推荐
相关产品推荐

