查看: 4164|回复: 3

Python f-string格式化实战:精度控制与常见报错避坑

[复制链接]
发表于 5 天前 | 显示全部楼层 |阅读模式
Python 3.6 引入的 f-string(Formatted String Literals)把变量和表达式直接写进字符串:前缀加 f 或 F,花括号 {} 里放要替换的内容。和 %-formatting、str.format() 相比,它省掉了格式符映射和参数传递,解释器在编译阶段就解析花括号内的表达式,因此执行效率更高,也更容易在拼接字符串时保持可读性。下面按“基础嵌入—格式控制—调试—错误排查—选型”的顺序,把常用写法和容易踩的坑集中梳理一遍。

一、变量、表达式与函数调用

f-string 的花括号内可以放任意合法 Python 表达式,包括算术运算、字符串方法、逻辑判断和函数调用。不需要提前把结果算出来再拼接,代码更紧凑:
  1. name = "Alice"
  2. age = 28
  3. print(f"姓名:{name},年龄:{age}") # 姓名:Alice,年龄:28
  4. print(f"明年年龄:{age + 1}") # 明年年龄:29
  5. print(f"姓名大写:{name.upper()}") # 姓名大写:ALICE
  6. print(F"姓名长度:{len(name)}") # 姓名长度:5
  7. a, b = 10, 3
  8. print(f"{a} + {b} = {a + b}") # 10 + 3 = 13
  9. print(f"{a} ÷ {b} = {a / b:.2f}") # 10 ÷ 3 = 3.33
  10. text = "python"
  11. print(f"首字母大写:{text.capitalize()}") # 首字母大写:Python
  12. print(f"是否为空:{len(text) == 0}") # 是否为空:False
  13. def get_full_name(first_name, last_name):
  14.     return f"{first_name} {last_name}"
  15. print(f"全名:{get_full_name('John', 'Doe')}") # 全名:John Doe
复制代码

这里要注意,花括号内写的是表达式而不是任意语句,表达式本身必须语法完整,函数调用要带括号,运算符不能悬空,否则会在编译阶段直接报 SyntaxError。

二、格式说明符:精度、宽度、对齐与进制

在花括号内用冒号引出格式说明符,写法和 str.format() 保持一致。常用的是“宽度.精度+类型字符”,例如 .2f 表示保留两位小数,10.4f 表示总宽度 10、保留四位小数。

浮点数场景:
  1. pi = 3.1415926535
  2. print(f"圆周率(保留2位):{pi:.2f}") # 3.14
  3. print(f"圆周率(宽度10,保留4位):{pi:10.4f}") # 右对齐,前面补空格,3.1416
  4. print(f"科学计数法:{pi:.2e}") # 3.14e+00
复制代码

整数场景主要用宽度、对齐和补零。d 表示十进制,x 和 o 分别输出十六进制和八进制;- 表示左对齐,0 表示左侧补零:
  1. num = 123
  2. print(f"右对齐:{num:10d}") # 宽度10,默认右对齐
  3. print(f"左对齐:{num:-10d}") # 宽度10,左对齐,右侧补空格
  4. print(f"补零:{num:010d}") # 0000000123
  5. print(f"十六进制(小写):{num:x}") # 7b
  6. print(f"八进制:{num:o}") # 173
复制代码

百分比用 % 类型符,数值会自动乘以 100 并追加百分号。默认保留 6 位小数,需要更短的结果时用 .2% 这样的精度限定:
  1. rate = 0.789
  2. print(f"百分比:{rate:%}") # 78.900000%
  3. print(f"百分比(保留2位):{rate:.2%}") # 78.90%
复制代码

三、日期时间与嵌套格式化

datetime 对象可以直接用日期格式符输出,不必先 strftime 再拼接:
  1. from datetime import datetime
  2. now = datetime.now()
  3. print(f"当前时间:{now:%Y-%m-%d %H:%M:%S}")
  4. print(f"今日日期:{now:%Y年%m月%d日}")
  5. print(f"今天是:{now:%A}") # 英文星期名
  6. print(f"今天是:{now:%w}") # 数字,0 表示周日
复制代码

当精度本身来自变量时,可以在格式说明符里再嵌一层花括号。下面 precision 为 2,最终按两位小数输出:
  1. precision = 2
  2. pi = 3.1415926535
  3. print(f"圆周率(保留{precision}位):{pi:.{precision}f}") # 3.14
复制代码

嵌套也可以用于条件表达式,但可读性会明显下降。层级较深时,建议先在普通变量里算出结果,再放进 f-string:
  1. score = 85
  2. print(f"成绩评级:{f'优秀({score}分)' if score >= 90 else f'良好({score}分)' if score >= 80 else '合格'}")
复制代码

四、调试写法:{变量=}

排查问题时,经常需要打印“变量名=值”。在花括号内变量后面加等号,可以自动输出变量名和值,还能继续接格式说明符:
  1. x = 10
  2. y = 20
  3. print(f"{x=}, {y=}, {x+y=}") # x=10, y=20, x+y=30
  4. print(f"{x=:05d}, {y=:.2f}") # x=00010, y=20.00
复制代码

这种写法适合临时调试,正式日志中仍建议使用 logging 并保留结构化字段,避免输出格式随变量名变化而失控。

五、常见错误与排查思路

1. 花括号内语法不完整

表达式缺少运算符右侧、括号不配对,都会让解释器在解析 f-string 时抛出 SyntaxError。变量未定义则是在运行阶段抛 NameError。遇到报错先检查花括号内是否是一个完整表达式,再确认变量作用域。
  1. # print(f"结果:{x + y *}")      # SyntaxError
  2. # print(f"未定义变量:{undefined_var}")  # NameError
复制代码

2. 引号冲突

外部字符串和内部表达式使用同一种引号时,容易提前结束字符串。处理方式是内外引号错开,或在内部使用转义符:
  1. # print(f"姓名:{name's}")  # SyntaxError
  2. print(f"姓名:{name}'s")     # 姓名:Alice's
  3. print(f'姓名:{name}\'s')    # 姓名:Alice's
复制代码

3. 浮点数精度误差

f-string 只改变显示格式,不改变浮点数的二进制存储结果。0.1 + 0.2 的真实结果仍是 0.30000000000000004,.1f 只是把显示结果四舍五入成 0.3。金融等高精度场景不要依赖格式化来“修正”数值,应改用 decimal 模块参与计算。
  1. a = 0.1
  2. b = 0.2
  3. print(f"0.1 + 0.2 = {a + b}") # 0.30000000000000004
  4. print(f"0.1 + 0.2 = {a + b:.1f}") # 显示为 0.3
复制代码

4. 版本兼容性

f-string 从 Python 3.6 开始支持。如果项目还要运行在 Python 3.5 及以下环境,只能回退到 str.format() 或 %-formatting。维护旧代码时,先确认目标解释器版本,再决定是否批量替换格式化写法。

六、三种格式化方式的选型

%-formatting 兼容所有 Python 版本,但格式符和参数需要按位置对应,参数一多就容易错位;str.format() 支持位置参数和关键字参数,从 Python 2.6、3.0 起可用,适合需要复用参数或动态拼接模板的场景;f-string 语法最简、执行效率最高,支持表达式、嵌套和格式说明符,但要求 Python 3.6+。

实际项目中可以这样取舍:新代码优先用 f-string;需要兼容旧解释器时用 str.format();维护历史代码或第三方模板时保留原有的 %-formatting。掌握花括号内嵌表达式、冒号后的格式说明符,以及引号冲突和浮点误差这两个高频问题,基本就能覆盖日常字符串格式化的绝大多数需求。
回复

使用道具 举报

发表于 5 天前 | 显示全部楼层

Re: Python f-string格式化实战:精度控制与常见报错避坑

整理得很清楚,基础嵌入、格式说明符、日期时间和调试写法都串起来了,尤其精度用变量嵌套和 {变量=} 这两点很实用。常见错误那部分也点到了关键:花括号里必须是完整表达式,报错先检查括号、运算符和变量作用域。百分比和日期格式直接写在 f-string 里确实省事,嵌套条件表达式则要注意可读性,复杂时先算到变量里再放进去更稳妥。感谢分享。
回复 支持 反对

使用道具 举报

发表于 5 天前 | 显示全部楼层

Re: Python f-string格式化实战:精度控制与常见报错避坑

楼主整理得很系统,例子覆盖了变量表达式、格式说明符、日期时间、嵌套精度和调试写法,尤其是“变量=”调试写法和百分比精度这些细节很实用。第五部分末尾好像被截断了,常见错误只看到 SyntaxError 和 NameError 的说明,后面排查思路还没发完,期待补全。整体读下来对宽度、对齐和精度控制的区分更清楚了,感谢分享。
回复 支持 反对

使用道具 举报

发表于 5 天前 | 显示全部楼层

Re: Python f-string格式化实战:精度控制与常见报错避坑

感谢楼主系统整理,f-string 这块讲得很全面,尤其是精度嵌套和调试写法这两节,平时确实容易忽略。 几点自己的体会补充交流一下:精度用变量那个 .{precision}f 真是实战利器,做报表或日志时特别省事;{x=} 这种调试写法我从 3.8 用上之后就离不开了,不过要注意它在 3.6/3.7 是不支持的,团队里如果有老版本环境得留意兼容性。另外第五部分提到的错误排查,我觉得还有个坑可以加上:f-string 里要输出字面花括号得写成双花括号,单写一个很容易漏掉;还有引号嵌套的问题,3.12 之前同一层不能复用相同引号,写复杂表达式时经常踩。 另外楼主的帖子好像没发完,最后停在“# p”那里,第五部分后面的内容和“选型”部分还没看到,期待补全,特别是选型那部分,想看看楼主对 f-string、format 和模板字符串各自适用场景的对比。再次感谢分享,已收藏。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-27 18:06 , Processed in 0.024685 second(s), 29 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部