f-string 比 str.format() 快因编译期拼接,后者需运行时解析模板、查变量、调用方法,多出至少两层函数调用;高频场景快1.5–2倍,但日常单次无感。

f-string 为什么比 str.format() 快
因为 f-string 在编译期就完成字符串拼接,而 str.format() 是运行时解析模板、查找变量、调用方法,多出至少两层函数调用和一次格式化引擎调度。
- 在循环里拼接日志或生成大量字符串时,f-string 的性能优势明显(实测快 1.5–2 倍)
-
str.format()需要先构造模板字符串,再传参;f-string 直接把表达式嵌进字符串字面量里,Python 解释器能提前做更多优化 - 注意:这个差距只在高频调用场景下才值得计较,日常单次拼接几乎感知不到
哪些地方 str.format() 还不能被 f-string 替代
f-string 不支持动态字段名、条件切换模板结构,也不方便复用同一套格式规则多次渲染不同数据。
- 需要运行时决定用哪个 key:
"{data[{key}]}"会报KeyError或语法错误;必须用"{data[key]}".format(data=data, key=key) - 想让同一段格式逻辑适配多个对象(比如统一加千分位、固定小数位),
str.format()配合Formatter子类更可控 - 国际化场景中,翻译后的模板含占位符顺序可能变化(如英文
"{name} is {age}"vs 中文"{name}今年{age}岁"),f-string 硬编码位置会导致维护困难
f-string 容易写错的三种情况
不是所有表达式都能直接塞进 {},Python 对里面的语法有严格限制。
- 不能有反斜杠:
f"路径:{os.path.join('a', 'b')}"没问题,但f"路径:{os.path.join('a', 'b\c')}"会因转义失败报SyntaxError - 不能嵌套花括号:
f"{{x}} = {x}"是合法的(双大括号表示字面量),但f"{ {x: y} }"会报错,字典/集合字面量必须外层加括号:f"{({x: y})}" - 不能在表达式里用赋值表达式(
:=)且后面还跟其他操作:f"{(x := 1) + 1}"可以,但f"{x := 1} 和 {x}"会报SyntaxError—— 海象运算符不能跨{}边界共享状态
调试时 print(f"…") 和 logging.debug("…".format()) 的取舍
print 用 f-string 更轻量,但 logging 如果开启 level 过滤(比如设为 WARNING),str.format() 仍会执行,造成不必要开销;f-string 则完全跳过。
立即学习“Python免费学习笔记(深入)”;
- 推荐日志一律用 lazy 格式化:
logging.debug("value=%s", value),既避免格式化开销,又保持可读性 - 如果非要用字符串插值,确保 logging 配置了
style='{'并用logging.debug("value={}", value),这是 logging 内部延迟解析,不会触发str.format() - 临时调试 print 没必要纠结,f-string 写起来快、意图清晰,但上线前建议删掉或改用 logging
str.format(**locals()) 那样“偷看”上层局部变量。遇到闭包或装饰器里动态注入上下文的情况,硬换 f-string 反而会让代码更难懂。








