调试代码的时候,直接print一个字典,输出的内容往往挤成一团,尤其是键名长短不一时,看起来非常费劲。Python的f-string从3.6版本开始就提供了强大的格式化能力,其中动态宽度控制可以让我们根据实际内容自动计算对齐宽度,实现整齐划一的打印效果。这篇文章就来详细讲讲具体的实现方法。

一、f-string格式化的基本语法:冒号后面藏着玄机
f-string的核心格式化语法是在表达式后面加上冒号,再跟上格式规范。完整的结构形如f"{value:format_spec}",其中format_spec由填充字符、对齐方式、符号、宽度、精度等部分组成。对齐相关的语法是重点:<表示左对齐,>表示右对齐,^表示居中对齐,紧跟其后的数字就是字段宽度。
举个最简单的例子,f"{'name':<10}"会把字符串name放在宽度为10的字段中左对齐,右侧自动补空格。而f"{'age':>10}"则右对齐,左侧补空格。如果不指定对齐符号只写宽度,比如f"{'age':10}",字符串默认左对齐,数字默认右对齐,这是初学者容易忽略的细节。
还可以在宽度前面指定填充字符,例如f"{'name':*<10}"会输出name******,用星号填满剩余空间。常用的填充字符有点号、横线等,适合做分隔线或表格边框。掌握了这些基础语法,下一步就可以用它来处理字典输出了。
user = {"name": "张三", "age": 28, "city": "北京"}
# 基本对齐示例
print(f"{'name':<10} = {user['name']}")
print(f"{'age':<10} = {user['age']}")
print(f"{'city':<10} = {user['city']}")二、动态宽度:根据最长键名自动计算对齐宽度
固定宽度有一个明显的缺陷:你得提前知道最长的键有多长。一旦字典内容变化,写死的宽度就不合适了。这时候可以用嵌套表达式把宽度参数变成动态计算的结果,这也是f-string最灵活的地方——格式规范的宽度位置本身可以放一个表达式。
具体做法是先遍历字典求出最长键名的长度,然后在格式化时把这个值嵌进去。语法上需要双层花括号嵌套,外层是普通的f-string表达式,内层的宽度表达式也要有自己的格式说明。写法是f"{key:<{width}}",其中width是一个变量。这种嵌套写法初次接触可能觉得别扭,但理解之后会发现它非常直观。
下面是完整的示例代码,演示如何让所有键名按照最长键的宽度对齐:
def print_dict_aligned(d, sep=": "):
# 计算最长键名的长度,作为对齐宽度
width = max(len(str(k)) for k in d.keys())
for k, v in d.items():
# 嵌套表达式:宽度位置嵌入变量 width
print(f"{str(k):<{width}}{sep}{v}")
config = {
"host": "127.0.0.1",
"port": 8080,
"timeout": 30,
"retry_count": 3
}
print_dict_aligned(config)运行后输出中每个键的冒号位置完全对齐,无论键名多长多短,整体排版都整齐划一。这种技巧在打印配置信息、生成日志摘要时特别实用,一眼就能扫到需要的信息。
如果想进一步美化,还可以在宽度计算时额外加几个字符的余量,比如width = max(len(str(k)) for k in d) + 2,让键和值之间留出呼吸空间,视觉上更舒适。
三、进阶玩法:居中对齐、数值精度与表格式输出
对齐方式不局限于左对齐。做表头时用居中对齐配合填充字符,可以快速生成有分隔感的标题行。同时,f-string对数值类型的格式化能力也很强,比如d表示整数、f控制小数精度、,添加千分位分隔符。把键名对齐和值格式化结合起来,就能输出漂亮的报表。
下面的例子综合了居中表头、动态宽度、数值格式化等多项技巧:
products = {
"机械键盘": 599.0,
"无线鼠标": 129.5,
"显示器支架": 289.9
}
# 居中表头,用横线填充
print(f"{'商品信息表':^^30}")
print(f"{'商品':<10}{'单价':>12}")
width = max(len(k) for k in products)
for name, price in products.items():
# 键左对齐,价格右对齐并保留两位小数
print(f"{name:<{width}}{price:>12.2f}")注意数值列一般用右对齐,这样小数点天然对齐,符合财务报表的习惯。如果数据中有很大的数字,加上千分位f"{num:,.2f}"会更易读。
对于嵌套字典,可以先递归处理内层,把内层字典先转成格式化字符串,再作为值传给外层的对齐逻辑。虽然f-string本身不负责递归,但配合一个简单的递归函数,多层结构的字典也能输出成缩进清晰的树状文本,调试复杂数据结构时非常方便。
最后提醒一点,f-string的嵌套格式化要求Python版本在3.6以上,而等号自文档化语法f"{value=}"则需要3.8以上。如果项目还在维护旧版本代码,可能需要改用str.format方法配合**{'width': width}的方式实现类似效果,不过写法要繁琐不少。总体来说,动态宽度格式化是f-string最值得掌握的特性之一,花点时间练习,能让你的调试输出质量提升一大截。