一、引言:从"老式"到"新式"的进化
Python 早期的 % 格式化继承自 C 语言的 printf,语法繁琐且类型绑定严格:
1 2 3
| name = "Alice" age = 30 print("Name: %s, Age: %d" % (name, age))
|
format() 作为 Python 2.6 引入的"新式"格式化方法,是 f-string 的前身,也是目前功能最全面的格式化方案。
核心观点:虽然 f-string 更简洁,但 format() 在模板分离和动态格式化场景中依然是王者。
二、基础语法:三种参数传递方式
2.1 位置参数
1 2 3 4 5
| "{} {}".format("Hello", "World")
"{1} {0} {1}".format("Hello", "World")
|
2.2 关键字参数
1 2 3 4 5 6 7
| "Hello, {name}! You are {age}.".format(name="Alice", age=30)
data = {"name": "Alice", "age": 30} "Hello, {name}! Age: {age}".format(**data)
|
2.3 混合使用
1 2
| "{0} is {age} years old. {0} lives in {city}.".format("Alice", age=30, city="Beijing")
|
建议保持清晰,避免过度混合。
三、核心进阶:格式说明符
冒号 : 后面的语法是 [[fill]align][sign][#][0][width][,][.precision][type]。
3.1 对齐与填充
1 2 3 4 5 6 7 8 9 10 11
| "{:<10}".format("hi")
"{:>10}".format("hi")
"{:^10}".format("hi")
"{:*^10}".format("hi")
|
3.2 数字格式化
精度控制:
1 2
| "{:.2f}".format(3.14159) "{:.0f}".format(3.14159)
|
千位分隔符——财务数据必备:
1 2
| "{:,}".format(1000000) "{:,.2f}".format(1234567.89)
|
百分比:
1 2
| "{:.1%}".format(0.25) "{:.2%}".format(1/3)
|
进制转换:
1 2 3 4
| "{:b}".format(42) "{:x}".format(42) "{:o}".format(42) "{:#x}".format(42)
|
符号控制:
1 2 3
| "{:+}".format(42) "{:+}".format(-42) "{: }".format(42)
|
3.3 动态宽度
1 2 3
| "{:{width}}".format("hi", width=10) "{:>{width}.{prec}f}".format(3.14159, width=10, prec=2)
|
四、高级技巧:访问对象与容器
4.1 访问属性
1 2 3 4 5 6 7
| class Person: def __init__(self, name, age): self.name = name self.age = age
p = Person("Alice", 30) "{p.name} is {p.age}".format(p=p)
|
4.2 访问字典键
1 2
| data = {"name": "Alice", "scores": [90, 85, 92]} "Name: {d[name]}".format(d=data)
|
4.3 访问列表索引
1 2
| items = ["apple", "banana", "cherry"] "First: {0[0]}, Last: {0[2]}".format(items)
|
| 维度 |
format() |
f-string |
| 语法 |
"{}".format(x) |
f"{x}" |
| 性能 |
中等 |
最快 |
| 模板分离 |
支持 |
不支持 |
| 动态格式化 |
支持 |
有限支持 |
| Python 版本 |
2.6+ |
3.6+ |
format() 的独特优势——模板与数据分离:
1 2 3 4 5 6 7 8 9 10
| templates = { "en": "Hello, {name}!", "zh": "你好,{name}!", "ja": "こんにちは、{name}!" }
lang = "zh" name = "Alice" print(templates[lang].format(name=name))
|
f-string 无法做到这一点,因为模板在编译期就被求值了。
日志格式定义:
1 2 3 4 5 6 7 8 9 10 11
| LOG_FORMAT = "[{level}] {time} - {message}"
def log(level, message): import datetime print(LOG_FORMAT.format( level=level, time=datetime.datetime.now().strftime("%H:%M:%S"), message=message ))
log("INFO", "Server started")
|
| 维度 |
format() |
% |
| 类型安全 |
自动处理 |
严格绑定(%s, %d, %f) |
| 字典映射 |
支持 {key} |
需 %(key)s |
| 元组处理 |
安全 |
单元素元组必须加逗号 |
| 功能丰富度 |
高 |
低 |
% 格式化的经典陷阱:
1 2 3
| "Value: %s" % (42,) "Value: %s" % (42)
|
六、总结与最佳实践
| 格式说明符 |
效果 |
示例 |
{:<10} |
左对齐,宽10 |
'hi ' |
{:>10} |
右对齐,宽10 |
' hi' |
{:^10} |
居中,宽10 |
' hi ' |
{:.2f} |
保留2位小数 |
'3.14' |
{:,} |
千位分隔 |
'1,000,000' |
{:.1%} |
百分比 |
'25.0%' |
{:b} |
二进制 |
'101010' |
{:+} |
显示正负号 |
'+42' |
专家建议:
- 在 Python 3.6+ 项目中优先使用 f-string——性能更好,语法更简
- 在需要动态构建格式字符串或处理模板文件时,坚持使用 format()——模板分离是它的核心优势
- 尽量避免在 Python 3 中使用 % 格式化——功能弱、陷阱多
- 善用字典解包
**data——让模板与数据自然对接