惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
F
Fortinet All Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
Y
Y Combinator Blog
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
IT之家
IT之家
V
V2EX
C
Check Point Blog
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
B
Blog
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
雷峰网
雷峰网

暗无天日

读:AI Agent 安全日志——从可见性与隐私的两难说起 - 暗无天日 AI写作的语言指纹——如何让文字不那么像机器 - 暗无天日 读:50 条 Claude Code 技巧——一个工程经理的六个月使用心得 读:AI 辅助开发为什么让 E2E 测试更有价值 - 暗无天日 读:在Emacs中使用Claude Code(Spacemacs适配版) - 暗无天日 Claude Code 背后的工程哲学——读 Agent Harness Engineering 读:Agent Harness Engineering——AI 智能体不只是模型,还有套件 - 暗无天日 browser-harness:让 AI 直接接管你的浏览器 - 暗无天日 读:Security-First CI/CD —— DevSecOps 自动化实践指南 TIL: 数字小键盘的小数点陷阱与行内算术求值 - 暗无天日 读:Immutability 不是万能药,它是一种权衡 - 暗无天日 Conducty:给 Claude Code 加上项目记忆和并行执行能力 - 暗无天日 读 — GitHub Trending 里的 Claude Code 技能包 读 — Prompt Caching 省钱指南 TIL: Emacs 中那些跟鼠标配合的冷门快捷键 - 暗无天日 读:Anvil——把 Emacs 变成 AI 的工具服务器 读:Emacs 代码折叠终极指南 - 暗无天日 读:Clojure 搭车客指南 - 暗无天日 git推送失败后恢复仓库损坏的完整记录 - 暗无天日 多智能体系统的两个有效模式——以及对 Claude Code 用户的启示 - 暗无天日 用 Org Babel 写 Literate 博文:扩展执行 + 定制导出 proced:Emacs 内置的进程查看器 - 暗无天日 从 proced 定制中学到的 Elisp 模式 读:让 Emacs proced 在 macOS 上显示 CPU 和内存 异步编程的函数着色税 - 暗无天日 链式调用的代价:JavaScript 和 Clojure 的共同教训 - 暗无天日 hyperfine:命令行基准测试工具 - 暗无天日 管道中的变量去哪了?——子 shell 作用域陷阱 - 暗无天日 开源包装器的信任陷阱:四个危险信号 - 暗无天日 程序员愿意为 AI 写文档,却不愿为同事写 - 暗无天日
TIL:lazy import 的具现化过程 - 暗无天日
lujun9972 · 2026-06-09 · via 暗无天日

Python 的 import 语句在模块加载时立即执行被导入模块的顶层代码。大型应用顶部可能 import 几百个模块,但其中很多不是马上用到的,全部在启动时执行意味着启动慢、内存浪费。CLI 工具对这个问题最敏感,用户敲完命令后超过半秒没响应就会觉得卡了。

为了解决这个问题,Python 3.15 引入了 lazy import 语法(来自 PEP 690),把模块加载推迟到首次使用时。写了 lazy import json 之后,=globals()["json"]= 拿到的不是一个模块对象,而是一个 lazy_import 类型的对象。这个对象不能调用 json.dumps() 之类的模块方法,它只是占着 json 这个名字,等真正需要用到模块时再被替换掉。如果这个 import 只在一个很少触发的错误处理分支里用到了,那这个模块可能永远不会被加载。

dir() 看看这个占位符有什么,

lazy import json
dir(globals()["json"])
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'resolve']

除了有一堆 dunder 方法(双下划线方法,像 __class____doc__ )之外,有个 resolve 方法。看看它的文档,

help(globals()["json"].resolve)
Help on built-in function resolve:

resolve() method of builtins.lazy_import instance
    resolves the lazy import and returns the actual object

手动调用 resolve()

lazy import json
resolved_json = globals()["json"].resolve()
resolved_json
<module 'json' from '/tmp/python3.15/lib/python3.15/json/__init__.py'>

拿到真实模块了。但有意思的是,globals 里的 lazy import 没有消失。

<lazy_import 'json'>

这说明具现化光靠 resolve() 不够。它分两步,先 resolve() 拿到模块,再赋值回 globals。

globals()["json"] = globals()["json"].resolve()

还有疑问

手动 resolve() 能拿到模块,但 lazy import 真正的自动具现化是什么操作触发的?Python 怎么检测到「有东西碰了这个 lazy import」并触发赋值?这个机制我还没搞明白。

(本文代码示例已在 Python 3.15.0a8 上实际验证通过。)