f-string 格式化字符串 (Formatted String Literals)
1. 定义
f-string 是 Python 3.6+ 的字符串写法:在字符串前加 f,然后在 {} 里直接写变量或表达式,运行时自动替换成它的值。是目前拼接字符串、打印日志最推荐的方式。
name = "Alice"
age = 25
print(f"{name} is {age} years old") # Alice is 25 years old一句话:
f"...{变量}..."= 把{}里的东西算出来,塞进字符串。 比+拼接和老式%格式化都清爽。
2. 拆解你的例子
print(f"lr={lr}: train_acc={train_acc_hist}, test_acc={test_acc_hist}")| 片段 | 含义 |
|---|---|
f"..." | f-string,{} 里会被求值替换 |
lr= | 普通文本,原样打印(这个 lr= 是字符串字面量,不是代码) |
{lr} | 变量 lr 的值被填进来 |
{train_acc_hist} | 变量 train_acc_hist 的值 |
: , | 分隔用的普通文本 |
假设 lr=0.01、train_acc_hist=0.95、test_acc_hist=0.92,输出:
lr=0.01: train_acc=0.95, test_acc=0.92
注意:
lr=里的lr是你手打的文本,{lr}里的lr才是变量。两个lr一个是标签、一个是值,别搞混。
3. 格式说明符(: 后面控制显示)
{值:格式} —— 冒号后面控制怎么显示,训练日志里极常用:
acc = 0.9567
n = 1234567
f"{acc:.2f}" # '0.96' 保留 2 位小数
f"{acc:.2%}" # '95.67%' 百分比 + 2 位小数
f"{n:,}" # '1,234,567' 千分位逗号
f"{acc:.4f}" # '0.9567' 保留 4 位
f"{42:03d}" # '042' 整数补 0 到 3 位
f"{acc:>10.2f}" # ' 0.96' 右对齐占 10 宽
f"{'hi':^8}" # ' hi ' 居中占 8 宽
f"{n:.2e}" # '1.23e+06' 科学计数法训练日志建议给准确率/损失加
:.4f或:.2%,否则0.9567000000001这种一长串很难看:print(f"lr={lr}: train_acc={train_acc:.2%}, test_acc={test_acc:.2%}") # lr=0.01: train_acc=95.67%, test_acc=92.30%
4. {} 里能放表达式(不只是变量)
f"{2 + 3}" # '5' 算术
f"{name.upper()}" # 'ALICE' 调方法
f"{len(items)}" # 列表长度
f"{arr.mean():.3f}" # 表达式 + 格式化
f"{'yes' if ok else 'no'}" # 三元表达式也行
f"{d['key']}" # 取字典值(注意引号别和外层冲突)5. {var=} 调试神器(Python 3.8+)
变量名后加 =,会同时打印变量名和值,调试超方便:
lr = 0.01
print(f"{lr=}") # lr=0.01 (自动带上 "lr=" 前缀!)
print(f"{train_acc=:.2%}") # train_acc=95.67%所以你的例子其实可以简写成:
print(f"{lr=}, {train_acc_hist=}, {test_acc_hist=}")省得手打
lr=、train_acc=这些标签,变量名改了也不会对不上。
6. 和老式写法对比
name, age = "Alice", 25
# ① f-string(推荐)
f"{name} is {age}"
# ② str.format()(较老)
"{} is {}".format(name, age)
"{n} is {a}".format(n=name, a=age)
# ③ % 格式化(最老,类似 C 的 printf)
"%s is %d" % (name, age)
# ④ 直接 + 拼接(麻烦,还要手动转字符串)
name + " is " + str(age)| 写法 | 可读性 | 备注 |
|---|---|---|
| f-string | 最好 | Python 3.6+,首选 |
.format() | 中 | 老代码/需要延迟格式化时 |
% | 差 | 遗留写法,尽量别用 |
+ 拼接 | 差 | 数字要 str(),易错 |
7. 常见坑
- 忘了前面的
f:"{lr}"(没 f)会原样打印{lr}而不是值——最常见的坑 - 引号冲突:f-string 外层用双引号,里面取字典就用单引号
f"{d['k']}",别双引号套双引号 - 大括号本身要打印:想输出字面的
{}要写{{和}},如f"{{{x}}}"→{值} {var=}是 3.8+:老 Python 不支持,会报语法错误- 格式化用错类型:
f"{'abc':.2f}"对字符串用.2f会报错,.2f只对数字 - f-string 里塞太复杂的逻辑:能算但可读性差,复杂计算先算好再放进去
8. 延伸阅读 / 关联概念
- 列表推导式与简写 — 另一类高频”一行流”写法;见
list-comprehension-idioms.md - 格式说明符完整语法 — 对齐、填充、进制、精度等(Format Specification Mini-Language)
print()参数 —sep、end、flush等控制输出行为- logging — 正式项目里比
print更规范的日志方式 - 官方文档:f-strings | Format Spec