上一章我们已经讲了两种字符串格式化方式:
一种是老牌的 %另一种是更灵活的 format()
它们都能用,也都很重要。 因为你以后看旧代码、看别人的项目、看很多教程时,依然会经常碰到。
但如果你问现在写 Python 时,哪种格式化方式最自然、最好写、最值得优先掌握,答案大概率就是:
f-string
这不是因为它更高级,也不是因为它更花哨。 而是因为它真的更顺手。
你会发现,很多以前要绕一下、写长一点、看起来有点别扭的格式化操作,到了 f-string 这里,一下就变得很自然。
这一章,我们就把 f-string 彻底讲透。
不是只讲语法,而是讲明白它为什么后来成了很多人最爱用的格式化方式。
一、什么是 f-string
先看一个最简单的例子:
name = '张三'print(f'你好,{name}')
输出:
你好,张三
这里你会发现,字符串前面多了一个字母 f。
这个 f 的意思可以简单理解成:
这是一个支持格式化的字符串
只要你在字符串前面加上 f, 那么字符串里的大括号 {} 就不再只是普通字符了,而会被当成一个可以放变量、表达式、结果的位置。
也就是说:
f'你好,{name}'
本质上就是:
先写一段字符串模板 再把变量 name 的值直接塞进去
这就是 f-string 的核心。
二、f-string 为什么第一眼就让人舒服
因为它非常接近人写句子的习惯。
比如上一章用 format() 写:
name = '李四'age = 20text = '我叫{},今年{}岁'.format(name, age)print(text)
而 f-string 写法是:
name = '李四'age = 20text = f'我叫{name},今年{age}岁'print(text)
你一眼就会觉得,后者更顺。
为什么?
因为变量就在它该出现的位置上。 你不需要先写一堆空的占位符,再回头去数第几个值填第几个坑。 你看到哪里,就知道那里会放什么。
这就是 f-string 最大的魅力之一:
可读性特别强
尤其是字符串稍微一长,这种优势会越来越明显。
三、f-string 和前两种写法放在一起看
我们拿同一个例子对比一下。
假设有这几个变量:
name = '王五'score = 93.5
用加号拼接:
print('学生' + name + '的成绩是' + str(score))
用 %:
print('学生%s的成绩是%.1f' % (name, score))
用 format():
print('学生{}的成绩是{:.1f}'.format(name, score))
用 f-string:
print(f'学生{name}的成绩是{score:.1f}')
你会发现,f-string 看起来最短,也最直白。
变量名直接写在大括号里 格式控制也直接跟在变量后面 不用再单独补一个 .format(...)也不用再去想 %s、%.1f 这些占位符和后面的值怎么一一对应
这就是为什么很多人一学到 f-string,就很难再回去用前两种写法写日常代码。
四、f-string 的基本用法其实特别简单
最基础的一条规则就是:
字符串前面加 f变量放到 {} 里
比如:
name = 'Python'print(f'我正在学习{name}')
输出:
我正在学习Python
再比如:
city = '杭州'print(f'我来自{city}')
输出:
我来自杭州
是不是比 % 和 format() 更像自然语言。
你几乎不用额外记什么复杂规则,就能先写起来。
五、f-string 可以一次放多个变量
当然可以。
比如:
name = '小明'age = 18city = '苏州'print(f'我叫{name},今年{age}岁,来自{city}')
输出:
我叫小明,今年18岁,来自苏州
这在日常输出里非常常见。
比如学生信息、商品信息、订单信息、提示语、欢迎语,基本都能这样写。
你会发现,大括号特别像一个个透明的小窗口。 变量是什么,最后窗口里就显示什么。
六、f-string 不只能放变量,还能直接放表达式
这是它特别爽的一点。
先看一个简单例子:
a = 10b = 20print(f'{a} + {b} = {a + b}')
输出:
10 + 20 = 30
注意最后那个 {a + b}。 这里不是变量,而是一个表达式。
这说明在 f-string 里,你不只是能塞变量, 还可以直接塞运算结果。
再比如:
price = 100discount = 0.8print(f'折后价是{price * discount}元')
输出:
折后价是80.0元
这就特别方便。
以前你可能要先算出一个结果,再定义变量,再格式化。 现在很多简单场景,直接写在大括号里就行。
七、为什么这一点很实用
因为真实写代码时,很多展示内容本来就带一点计算。
比如:
总价 平均分 折后价 库存差值 完成百分比 两个时间的差
比如学生平均分:
chinese = 90math = 95english = 88print(f'平均分是{(chinese + math + english) / 3}')
比如商品总价:
price = 59.9count = 3print(f'总价为{price * count}元')
你会发现,这种写法让 输出 和 计算 自然地连在了一起。
这就是 f-string 为什么会让人觉得顺手。 因为它不像是在拼字符串,更像是在把结果直接写进句子里。
八、f-string 也能调用简单方法
比如:
name = 'python'print(f'{name.upper()}')
输出:
PYTHON
再比如:
text = ' hello 'print(f'处理后的结果是:{text.strip()}')
输出:
处理后的结果是:hello
这说明,大括号里并不只是能放一个变量名。 只要是合理的表达式、方法调用、结果计算,都可以写进去。
不过这里有个建议:
能写,不代表应该写得太复杂。
简单表达式放进去很舒服。 但如果你把很长很绕的逻辑全塞进一对大括号里,代码就会变得难读。
这一点后面我会再专门提醒。
九、f-string 怎么控制小数位数
这也是最常见、最实用的功能之一。
比如一个价格:
price = 19.8print(f'价格:{price:.2f}元')
输出:
价格:19.80元
这里的 :.2f 和上一章 format() 的规则非常像。
你可以这样理解:
冒号后面写格式要求.2f 表示保留 2 位小数
再看一个:
score = 93.4567print(f'成绩:{score:.1f}分')
输出:
成绩:93.5分
这说明 f-string 并不是只是看起来简洁,它连格式控制能力也一起继承过来了。
所以你可以把它理解成:
既有 format() 的格式能力 又有更自然的写法
十、f-string 控制整数、浮点数输出时特别舒服
比如你做成绩单:
name = '张三'score = 96.235print(f'学生{name}的成绩是{score:.2f}分')
输出:
学生张三的成绩是96.24分
再比如你做商品展示:
product = '蓝牙音箱'price = 299discount = 8.5print(f'商品:{product},价格:{price:.2f}元,折扣:{discount:.1f}折')
输出:
商品:蓝牙音箱,价格:299.00元,折扣:8.5折
你会发现,f-string 最大的一个优点就是:
变量和格式控制写在一起
不像 % 那样前面一套规则、后面一串值分开看。 也不像 format() 那样模板和参数是两块。
它几乎把所有东西都摆在你眼前了。
十一、f-string 还能控制对齐
这个在表格输出、日志排版、命令行展示里很实用。
比如:
name = 'Tom'print(f'|{name:10}|')
输出大概是:
|Tom |
也就是给它留出 10 个字符宽度。
如果你想右对齐:
print(f'|{name:>10}|')
输出大概是:
| Tom|
如果你想居中:
print(f'|{name:^10}|')
输出大概是:
| Tom |
你会发现,这一套规则和 format() 很像。 因为 f-string 本来就吸收了很多 format() 的能力。
这也是为什么它后来会越来越受欢迎。 因为它不是牺牲能力来换简洁,而是尽量把两者都保住了。
十二、来看一个更完整的成绩单例子
假设有下面这些数据:
name = '李四'chinese = 95math = 91english = 88.6
如果用 f-string 输出:
print(f'学生:{name},语文:{chinese}分,数学:{math}分,英语:{english:.1f}分')
输出:
学生:李四,语文:95分,数学:91分,英语:88.6分
再进一步,如果你还想顺手带上总分:
print(f'学生:{name},总分:{chinese + math + english:.1f}分')
输出:
学生:李四,总分:274.6分
你看,这里就很能体现 f-string 的优势。
展示 计算 格式控制
几乎都能放在一条表达里自然完成。
十三、再看一个商品结算场景
比如:
product = '机械键盘'price = 299.0count = 2discount = 0.9
输出订单信息:
print(f'商品:{product}')print(f'单价:{price:.2f}元')print(f'数量:{count}')print(f'折后总价:{price * count * discount:.2f}元')
输出大概是:
商品:机械键盘单价:299.00元数量:2折后总价:538.20元
这种写法放在真实项目里真的很自然。 因为你不需要先写很多中间变量,也不需要反复拼接。
当然,如果计算逻辑本身已经比较复杂,那还是建议先算好,再格式化。 这一点等下我会专门说。
十四、f-string 为什么会成为最推荐的方式
这里我们把原因说透一点。
第一,写法最直观。 变量就写在它出现的位置上,不用跳来跳去看。
第二,可读性强。 尤其是变量多的时候,别人一眼就知道哪一块输出对应哪个值。
第三,支持表达式。 很多简单计算、方法调用、格式控制都能直接写进去。
第四,格式能力不弱。 小数、宽度、对齐,这些常见需求都能处理。
第五,日常开发真的省心。 写提示语、日志、报表、调试信息时,体验非常顺。
所以它后来越来越受欢迎,并不是因为大家嫌旧写法土, 而是因为它确实更符合写代码时的直觉。
十五、f-string 和 format 放在一起,谁更推荐
如果是现在自己写新代码, 大多数日常场景下,f-string 更推荐。
比如:
name = '张三'score = 95.6print(f'学生{name}的成绩是{score:.1f}分')
通常就会比:
print('学生{}的成绩是{:.1f}分'.format(name, score))
更自然一点。
但这不代表 format() 没用了。
因为:
你以后还是会看到它 你还是需要看懂它 某些场景里它依然很好用
所以最稳的学习方式不是二选一,而是:
理解 %会用 format()日常优先掌握 f-string
这样最全面。
十六、f-string 也有边界,不是什么都该往里塞
这一点非常重要。
很多人学到这里,会觉得太方便了,于是什么都想往大括号里写。
比如很复杂的计算、很多层判断、很长的方法链,全部塞进去。 这就会让字符串看起来很乱。
比如这种写法虽然能跑,但就不太建议:
a = 10b = 20c = 30print(f'结果是{(a + b) * c / (a - 3) + (b * 2 - c / 5)}')
你当然能这么写。 但读起来已经有点费劲了。
更好的方式通常是:
先把复杂逻辑算好 再把结果放进 f-string
比如:
a = 10b = 20c = 30result = (a + b) * c / (a - 3) + (b * 2 - c / 5)print(f'结果是{result}')
这样代码会更清楚。
所以一个很实用的原则是:
简单表达式可以直接放 复杂逻辑先算再放
f-string 是为了让代码更清晰, 不是为了把所有逻辑都挤进一行。
十七、f-string 最适合哪些场景
特别适合这些地方:
打印提示信息 拼展示文本 输出成绩、价格、数量 生成日志内容 快速调试变量 写脚本时看运行结果 做命令行工具的文本输出
比如调试时:
name = 'Tom'age = 18print(f'name={name}, age={age}')
这种写法非常顺手。
你以后写代码调试变量,经常会不自觉地就用上。
十八、一个特别常见的实战场景:欢迎语
比如:
username = 'admin'login_time = '2026-03-26 10:30'
输出欢迎信息:
print(f'欢迎你,{username},本次登录时间是 {login_time}')
如果你还想加点格式:
balance = 520.678print(f'当前账户余额:{balance:.2f}元')
这种需求你以后做用户系统、自动化脚本、后台工具时都会经常见到。
十九、一个特别常见的实战场景:循环里批量输出
比如你有学生名单:
students = ['张三', '李四', '王五']
批量输出:
for name in students: print(f'欢迎{name}来到Python课堂')
这在 for 循环里尤其顺手。 因为变量每次变化,f-string 就能自然地跟着展示新内容。
再比如打印编号:
for i in range(1, 4): print(f'第{i}次执行完成')
这种提示信息在脚本里特别高频。
二十、f-string 和字符串方法结合起来也很顺
比如:
name = 'python'print(f'大写后是:{name.upper()}')
再比如:
text = ' hello world 'print(f'清理后结果:{text.strip()}')
再比如:
filename = 'report.pdf'print(f'文件后缀检查结果:{filename.endswith(".pdf")}')
你会发现,f-string 很适合把 处理动作 和 展示结果 放在同一个地方表达出来。
当然,还是那句话:
简单的这样写很舒服 太复杂了就别硬塞
二十一、f-string 最容易犯的几个错
先说第一个。
忘了在字符串前面加 f。
比如:
name = '张三'print('你好,{name}')
输出会是:
你好,{name}
因为这时候它只是普通字符串,大括号不会生效。
正确写法是:
print(f'你好,{name}')
第二个错,是大括号没配对好。 比如少写一个、或者写多一个,就会报错。
第三个错,是把太复杂的逻辑一股脑塞进去,导致代码难读。 这个前面已经提醒过。
第四个错,是格式控制位置写错。 比如小数位规则应该写在变量后面、冒号后面:
price = 19.8print(f'{price:.2f}')
别把顺序写乱。
二十二、什么时候不适合硬用 f-string
如果你只是处理一段完全固定的普通文本,那当然没必要上 f-string。
比如:
print('欢迎来到Python世界')
这就够了。
再比如,如果格式模板本身来自外部输入,或者你需要更偏模板化、配置化的写法,有时候 format() 也 still 很合适。
所以不是说学了 f-string 以后,别的方法都该扔。 而是说:
日常绝大多数需要把变量塞进字符串里的场景,f-string 通常是第一选择
二十三、把三种写法最后再一起看一遍
比如:
name = '小明'score = 92.567
% 写法:
print('学生%s的成绩是%.1f分' % (name, score))
format() 写法:
print('学生{}的成绩是{:.1f}分'.format(name, score))
f-string 写法:
print(f'学生{name}的成绩是{score:.1f}分')
三种都能用。 但你大概率已经能感觉到:
f-string 最像你脑子里原本想写出来的样子。
这就是它为什么后来越来越成为推荐写法。
二十四、练习题:这章非常值得自己手敲
下面这些小练习很典型,建议你自己写一遍。
1. 用 f-string 输出一句自我介绍
name = '张三'age = 18print(f'我叫{name},今年{age}岁')
2. 用 f-string 输出商品和价格,价格保留 2 位小数
product = '鼠标'price = 59.9print(f'商品:{product},价格:{price:.2f}元')
3. 在 f-string 里直接计算两个数的和
a = 10b = 20print(f'{a} + {b} = {a + b}')
4. 用 f-string 输出三门成绩的平均分,保留 1 位小数
chinese = 90math = 95english = 88print(f'平均分:{(chinese + math + english) / 3:.1f}')
5. 用 f-string 控制名字在 10 个字符宽度里右对齐
name = 'Tom'print(f'|{name:>10}|')
6. 先把字符串去掉两边空格,再用 f-string 展示结果
text = ' hello python 'print(f'处理后的结果是:{text.strip()}')
这些题不难,但特别能帮你把 f-string 的手感建立起来。
二十五、本章小结
这一章你真正要带走的,不只是一个新语法,而是一种更自然的格式化方式。
f-string 的核心很简单:
字符串前面加 f变量或表达式放进 {}需要格式控制时,在里面继续写规则
它之所以后来成了很多人最推荐的格式化方式,原因也很清楚:
写法直观 可读性强 支持表达式 格式控制方便 非常适合日常开发
如果说 % 是经典老写法,format() 是更灵活的过渡写法, 那 f-string 就更像是把格式化这件事真正写顺了的一种方式。
从这一章开始,你以后写提示语、成绩单、商品信息、日志内容,大概率都会越来越自然地想到 f-string。
下一章我们继续讲 转义字符与原始字符串:路径问题一次讲明白。 到那一章,你会发现,字符串不只是格式化会让人犯迷糊,路径里的斜杠、换行、制表符这些东西,也常常是新手的大坑。