Python 模块只会被加载一次吗?

Python模块默认只加载一次,重复import直接返回sys.modules中缓存的模块对象;首次导入执行顶层代码并缓存,后续导入跳过执行;可用importlib.reload()强制重载,但不更新已有引用。

是的,Python 模块默认只会被加载(导入)一次。重复 import 同一个模块不会重新执行其代码,而是直接返回已缓存在 sys.modules 中的模块对象。

模块缓存机制:sys.modules 是关键

Python 在首次导入模块时,会执行模块文件中的顶层代码(如函数定义、变量赋值、print 语句等),然后将模块对象存入 sys.modules 字典,键为模块名。后续 import 都会先查这个字典——命中就直接返回,跳过加

载和执行。

  • 你可以手动检查:import sys; print('mymodule' in sys.modules)
  • 也可以清空缓存强制重载(不推荐生产环境用):del sys.modules['mymodule'],再 import 就会重新执行

import 语句本身不等于“重新加载”

写多次 import mathfrom os import path 不会让代码重复运行,也不会增加开销。Python 解释器在编译阶段就能识别重复导入并优化掉。

  • 即使在函数里反复写 import json,也只会在第一次调用时触发加载
  • 但习惯上仍建议把 import 放在文件顶部,提高可读性和一致性

想重新加载?得用 importlib.reload()

如果开发中修改了模块代码又不想重启解释器(比如在 Jupyter 或调试时),可以用 importlib.reload() 强制重载:

  • 必须先成功 import 过该模块,否则 reload 会报错
  • import mymod; import importlib; importlib.reload(mymod)
  • 注意:reload 不会更新已存在的引用。例如 from mymod import func 导入的 func 不会自动更新,需重新执行 from 导入或改用模块点号访问

包内子模块的导入也受同一规则约束

同一个包下的不同模块,只要名字不重复,各自独立缓存;但若 A.py 做了 import B,B.py 又做了 import A(循环导入),Python 会利用 sys.modules 的占位机制避免无限递归——不过此时模块可能处于“部分初始化”状态,容易引发 AttributeError。

  • 避免在模块顶层直接使用尚未完全初始化的跨模块对象
  • 把依赖延迟到函数内部(即“延迟导入”)通常是更安全的做法