f-string比format()更快,因其在编译期完成拼接,而format()需运行时解析模板、查变量、调用方法,多出至少两层函数调用和一次格式化引擎调度。

因为f-string在编译期就完成拼接,format()必须在运行时解析模板、查变量、调用方法——多出至少两层函数调用和一次格式化引擎调度。
f-string 是编译期求值,format() 是运行时解析
Python 解释器看到 f"hello {name}",会在 AST(抽象语法树)阶段就把表达式 name 绑定到字符串字面量中,生成类似 "hello " + str(name) 的字节码;而 "hello {}".format(name) 每次执行都要:构造 Formatter 实例 → 扫描字符串找 {} → 匹配参数位置 → 调用 __format__ 或类型转换 → 拼接结果。
这意味着:
- 循环内高频拼接(如日志、CSV 行生成)时,
f""实测快 1.5–2 倍 -
format()的开销不随字符串复杂度线性增长,但随占位符数量上升明显 - 哪怕只拼一个变量,
f"{x}"也比"{}".format(x)少一次方法查找和参数绑定
format() 的参数复用机制反而拖慢单次调用
format() 设计初衷是支持“模板复用”,比如先存 tmpl = "id={id}, name={name}",再多次调用 tmpl.format(...)。但单次使用时,这个机制成了累赘:
- 每次调用都得重新解析
tmpl字符串(哪怕内容完全一样) - 关键字参数要构建 dict,位置参数要打包 tuple,再做字段映射
- 遇到
{0} {name}这类混用写法,直接抛ValueError: cannot switch from automatic field numbering to manual field specification
f"" 没这问题:f"{id} {name}" 就是纯表达式求值,无编号、无命名、无解析。
性能差距只在高频场景才值得计较
单次拼接(比如初始化配置提示、一次性错误消息)几乎感知不到差异——timeit 测出来可能也就纳秒级差别。真正吃性能的地方是:
- Web 请求循环里拼 HTTP 头或 JSON 片段
- 数据导出时逐行生成 CSV/TSV
- 异步任务中高频打 debug 日志
这时候 f"" 省下的函数调用和对象分配,会累积成可观的 CPU 时间节省。但别为了“理论上更快”把 format() 全删掉——比如动态字段名 "{data[{key}]}" 在 f"" 里写不出,只能靠 format() 或 string.Template。
最容易被忽略的是调试场景:f"{x=}" 不仅省打字,还避免了 print("x=" + str(x)) 可能触发的 __str__ 副作用;但如果你在 logging 里写 logging.debug(f"value={heavy_func()}"),而日志 level 是 WARNING,那 heavy_func() 依然会被执行——这点和 format() 一样,不是真正的延迟求值。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











