“Python 3.15 的 lazy import 到底省多少启动时间、会不会让出错的位置变得更难找” 是升级前最该先测的新语法。这篇在本机用 Python 3.14.9 和 3.15.0 并排跑同一份代码,量出 15 个标准库模块的启动开销,复现出错时机的变化和不能写 lazy import 的位置,并试了不改代码的 -X lazy_imports=all。
Python 3.14(退出码 1):
File "<tmp>/s1.py", line 3
lazy import side
^^^^^^
SyntaxError: invalid syntax
Python 3.15(退出码 0):
lazy import 之后: side 的类型 = lazy_import | 在 sys.modules 里: False
[side.py 正在执行]
第一次用 side.VALUE -> 7
之后: side 的类型 = module | 在 sys.modules 里: True
Python 3.15:lazy from … import(退出码 0):
lazy from side import VALUE 之后,这行先执行
[side.py 正在执行]
第一次用 VALUE: 83.14 不认识 lazy import;3.15 里导入语句不执行模块,第一次用到名字时才导入,名字从 lazy_import 对象变成 module。
Python 3.15(退出码 1):
lazy import 一个不存在的模块,这行照常执行
Traceback (most recent call last):
File "<tmp>/s4.py", line 2, in <module>
lazy import no_such_module_xyz
ImportError: lazy import of 'no_such_module_xyz' raised an exception during resolution
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<tmp>/s4.py", line 4, in <module>
no_such_module_xyz.f()
^^^^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named 'no_such_module_xyz'
Python 3.15:sys.lazy_modules 与全局模式(退出码 0):
lazy 导入之后 sys.lazy_modules 里有 side: True | 有 json: True
sys.get_lazy_imports() = normal不存在的模块在 lazy import 那一行不报错,第一次使用时才抛出,traceback 是 ImportError 链加 ModuleNotFoundError。
try / except 里(退出码 1):
SyntaxError: lazy import not allowed inside try/except blocks
函数里(退出码 1):
SyntaxError: lazy import not allowed inside functions
类里(退出码 1):
SyntaxError: lazy import not allowed inside classes
lazy from … import *(退出码 1):
SyntaxError: lazy from ... import * is not allowed
-X lazy_imports=all 时,try 里的普通 import(退出码 0):
try 里的 import 立即报了 ImportErrortry/except、函数、类里和 import * 是编译期 SyntaxError;全局 all 模式也不碰 try 里的普通 import。
-X lazy_imports=all(退出码 0):
全局 all 模式下,普通 import side 之后在 sys.modules 里: False
sys.get_lazy_imports() = all
PYTHON_LAZY_IMPORTS=all(退出码 0):
sys.get_lazy_imports() = all
side 在 sys.modules 里: False
Python 3.14 加 -X lazy_imports=all(退出码 0):
[side.py 正在执行]
x
过滤器:side 不延迟(退出码 0):
filter 被调用: __main__ side None
[side.py 正在执行]
filter 被调用: __main__ json None
side 已导入: True | json 已导入: False-X lazy_imports=all 或 PYTHON_LAZY_IMPORTS=all 不改代码就让顶层 import 变延迟;3.14 上这个选项被静默忽略;sys.set_lazy_imports_filter 可以排除个别模块。
写法 中位数 ms 最小 ms 最大 ms 启动后 sys.modules 里的模块数 3.14 空脚本(基线) 18.9 17.4 21.3 33 3.15 空脚本(基线) 18.9 17.3 20.9 33 3.14 普通 import 91.1 85.5 102.9 238 3.15 普通 import 100.3 92.6 109.3 242 3.15 lazy import 19.4 18.5 23.7 33 3.15 lazy import 然后用到 json 24.4 22.1 26.2 58 3.15 普通 import + -X lazy_imports=all 18.9 17.2 28.2 33 3.15 里 15 个模块的导入开销:普通 import 比空脚本多 81.4 ms,lazy import 比空脚本多 0.5 ms 3.14 里 15 个模块的导入开销:普通 import 比空脚本多 72.1 ms
导入 15 个标准库模块但没用到:普通 import 比空脚本多约 81 ms,lazy import 只多 0.5 ms,代价是推迟到第一次使用。