大家好,欢迎来到IT知识分享网。
3 f-string (格式化字符串) in Python
自 Python 3.6 引入以来,f-string 提供了一种更加简洁和直观的方式来进行字符串格式化。其语法简单明了:只需在字符串前加上字母
f
或F
,并在字符串中使用{}
来包裹需要插入的内容。
使用 f-string 的样例:
msg = 'hello world' print(f'msg: {
msg}') # 输出:msg: hello world
这就可以了!再也不需要用 string.format
或者 %
了。不过 f-string 并不能完全替代 str.format
。本文也将列举出这两者并不通用的情况。
基本的字符串格式化
如上文所述,使用 f-string 格式化字符串十分简单。唯一的要求就是给它一个有效的表达式。f-string 也可以用大写 F
开头或者与 r
原始字符串结合使用。但是你不能将其与 b""
或者 u""
混用。
book = "The dog guide" num_pages = 124 print(f"The book {
book} has {
num_pages} pages") # 输出:The book The dog guide has 124
f-string 的限制
虽然 f-string 十分便捷,但它并不能完全代替 str.format
。f-string 在表达式出现的上下文中进行求值计算。根据 PEP 498,这意味着该表达式可以获取所有局部和全局变量。而且该表达式是在运行时计算的表达式。如果在 { <expr> }
之中使用的表达式无法被计算,就会跳出如下异常。
f"{
name}" # NameError: name 'name' is not defined
这对 str.format
来说就不是问题,你可以提前定义一个模板字符串,并在之后调用 .format
方法时再传递上下文信息。
s = "{name}" print(s.format(name="Python")) # 输出:Python print(s) # 输出:{name}
另外还有个限制是,你不能在 f-string 中使用行内注释。
f"My name is {
name #name}!" # SyntaxError: f-string expression part cannot include '#'
如何格式化一个表达式
如果不想定义变量,那你可以在大括号中使用常量。Python 会计算该表达式并显示最终计算结果。
print(f"4 * 4 is {
4 * 4}") # 输出:4 * 4 is 16
或者你可以…
n = 4 print(f"4 * 4 is {
n * n}") # 输出:4 * 4 is 16
如何使用 f-string 来调试代码
调试是 f-string 最常见的用途之一了。Python 3.8 之前,很多人会用一种非常繁杂的 hello = 42; f"hello = {hello}"
来进行调试。针对此 Python 3.8 引入了一个新功能。你可以用 f"{hello=}"
重写上面的代码,而 Python 会显示 hello=42
。下面这个例子展示了在使用函数表达式时如何应用该特性,其原理与上文代码是一样的。
def magic_number(): return 42 print(f"{
magic_number() = }") # 输出:magic_number() = 42
如何格式化数字的不同进制
f-string 还能在不同进制下显示数字。例如,你不需要通过 b
来对一个 int
进行格式转化就可以显示其二进制结果。
print(f'{
7:b}') # 输出:111
总结一下就是你可以用 f-string 来格式化:
- int 到二进制
- int 到十六进制
- int 到八进制
- int 到十六进制(所有符号大写)
下面的例子使用缩进功能和进制格式化创建了一个表,可以显示数字在不同进制下的值。
bases = {
"b": "bin", "o": "oct", "x": "hex", "X": "HEX", "d": "decimal" } for n in range(1, 21): for base, desc in bases.items(): print(f"{
n:5{
base}}", end=' ') print()
如何用 f-string 打印对象
你可以用 f-string 打印自定义对象。默认设置是,如果你向 f-string 表达式传递了一个对象,它将会显示该对象 __str__
方法的返回值。不过,你也可以用显式转换操作标志来打印 __repr__
的值。
!r
– 使用repr()
将值转化为文本。!s
– 使用str()
将值转化为文本。
class Color: def __init__(self, r: float = 255, g: float = 255, b: float = 255): self.r = r self.g = g self.b = b def __str__(self) -> str: return "A RGB color" def __repr__(self) -> str: return f"Color(r={
self.r}, g={
self.g}, b={
self.b})" c = Color(r=123, g=32, b=255) # 如不加任何操作符, 会打印 __str__ 的值 print(f"{
c}") # 输出:A RGB color # 用 `obj!r` 的话会打印 __repr__ 的值 print(f"{
c!r}") # 输出:Color(r=123, g=32, b=255) # 使用 `!s` 跟默认值一样 print(f"{
c!s}") # 输出:A RGB color
Python 也允许通过定义不同类型使用 __format__
方法控制格式化结果,下面的例子会展示所有可能情况。
class Color: def __init__(self, r: float = 255, g: float = 255, b: float = 255): self.r = r self.g = g self.b = b def __str__(self) -> str: return "A RGB color" def __repr__(self) -> str: return f"Color(r={
self.r}, g={
self.g}, b={
self.b})" def __format__(self, format_spec: str) -> str: if not format_spec or format_spec == "s": return str(self) if format_spec == "r": return repr(self) if format_spec == "v": return f"Color(r={
self.r}, g={
self.g}, b={
self.b}) - A nice RGB thing." if format_spec == "vv": return ( f"Color(r={
self.r}, g={
self.g}, b={
self.b}) " f"- A more verbose nice RGB thing." ) if format_spec == "vvv": return ( f"Color(r={
self.r}, g={
self.g}, b={
self.b}) " f"- A SUPER verbose nice RGB thing." ) raise ValueError( f"Unknown format code '{
format_spec}' " "for object of type 'Color'" ) c = Color(r=123, g=32, b=255) print(f'{
c:v}') # 输出:Color(r=123, g=32, b=255) - A nice RGB thing. print(f'{
c:vv}') # 输出:Color(r=123, g=32, b=255) - A more verbose nice RGB thing. print(f'{
c:vvv}') # 输出:Color(r=123, g=32, b=255) - A SUPER verbose nice RGB thing. print(f'{
c}') # 输出:A RGB color print(f'{
c:s}') # 输出:A RGB color print(f'{
c:r}') # 输出:Color(r=123, g=32, b=255)
最后,还有个用来转义 ASCII 字符的 a
操作符。更多信息可参考 官方文档。
utf_str = "Áeiöu" print(f"{
utf_str!a}") # 输出:'\\xc1ei\\xf6u'
如何用 f-string 设定浮点数精度
F-string 可以像 str.format
那样格式化浮点数。想要实现这一点,你需要加一个 :
(冒号)再加一个 .
(英文句号)然后跟着小数点位数最后以 f
结尾。
举例来说,你可以通过如下代码打印一个浮点数精确到百分位的近似值。
num = 4. print(f"num rounded to 2 decimal places = {
num:.2f}") # 输出:num rounded to 2 decimal places = 4.12
不加任何选项的话,则会打印浮点数本身的精确值。
print(f'{
num}') # 输出:4.
如何将一个数字格式化为百分数
Python f-string 方法有个非常便捷的实现格式化百分数的操作方法。方法与浮点数格式化类似,但是要用 %
代替结尾的 f
。它会将原始数值乘以 100 并显示成有百分符号的固定格式。精度一样也是可以设定的。
total = 87 true_pos = 34 perc = true_pos / total print(f"Percentage of true positive: {
perc:%}") # 输出:Percentage of true positive: 39.080460% print(f"Percentage of true positive: {
perc:.2%}") # 输出:Percentage of true positive: 39.08%
如何调整或者增加 f-string 的填充
你可以便捷地通过 <
或者 >
符号来调整字符串填充。
greetings = "hello" print(f"She says {
greetings:>10}") # 输出:She says hello # Pad 10 char to the right print(f"{
greetings:>10}") # 输出: hello print(f"{
greetings:<10}") # 输出:hello # You can omit the < for left padding print(f"{
greetings:10}") # 输出:hello
a = "1" b = "21" c = "321" d = "4321" print("\n".join((f"{
a:>10}", f"{
b:>10}", f"{
c:>10}", f"{
d:>10}"))) # 输出: # 1 # 21 # 321 # 4321
如何转义符号
如果你想打印由大括号括起来的变量名称,而不是该变量的值,那你需要双层大括号 {
。
{<expr>}}
hello = "world" print(f"{
{hello}} = {
hello}") # 输出:{hello} = world
而如果你想转义双引号,就需要在引号前用反斜线 \
做标记。
print(f"{
hello} = \"hello\"") # 输出:world = "hello"
如何使字符串居中
想要实现字符串居中,可以通过 var:^N
的方式。其中 var
是你想要打印的变量,N
是字符串长度。如果 N
小于 var
的长度,会打印全部字符串。
hello = "world" print(f"{
hello:^11}") # 输出: world print(f"{
hello:*^11}") # 输出:*world* print(f"{
hello:*^10}") # 输出:world* print(f"{
hello:^2}") # 输出:world
如何格式化千分位
F-string 也允许我们自定义数字显示的格式。有个非常普遍的需求就是把数字以每 3 位为一个间隔使用下划线进行分隔。
big_num = print(f"{
big_num:_}") # 输出:1_234_567_890
如何使用逗号千分位分隔符数字
实际上,你可以随便用任何符号做千分位分隔符。所以用逗号做分隔符也完全没问题。
big_num = print(f"{
big_num:,}") # 输出:1,234,567,890
甚至可以一次性同时搞定既有千分位分隔符又有精度设定的浮点数。
num = . print(f"{
num:,.3f}") # 输出:2,343,552.652
如何用空格做千分位分隔符
用空格也可以吗?好吧,这个问题是挺棘手,不过也能实现。你可以用逗号做分隔符之后再用空格替换逗号。
big_num = print(f"{
big_num:,}".replace(',', ' ')) # 输出:1 234 567 890
还有个方法是设定你的本地语言环境,换成一个用空格作千位分隔符的环境比如 pl_PL
(波兰语环境)。更多信息可参考这个 Stack Overflow 链接。
如何用科学计数法(指数计数法)显示一个数字
可以用 e
或者 E
字符来格式化。
num = . print(f"{
num:e}") # 输出:2.e+06 print(f"{
num:E}") # 输出:2.E+06 print(f"{
num:.2e}") # 输出:2.34e+06 print(f"{
num:.4E}") # 输出:2.3436E+06
在 f-string 中使用 if-else
F-string 也能计算稍微复杂的运算式,比如 if/else。
a = "this is a" b = "this is b" print(f"{
a if 10 > 5 else b}") # 输出:this is a print(f"{
a if 10 < 5 else b}") # 输出:this is b
如何在 f-string 中使用字典
你可以在 f-string 中使用字典。唯一的要求是引起整个字符串的引号要跟内部的引号不一样。
color = {
"R": 123, "G": 145, "B": 255} print(f"{
color['R']}") # 输出:123 print(f'{
color["R"]}') # 输出:123 print(f"RGB = ({
color['R']},{
color['G']}, {
color['B']})") # 输出:RGB = (123, 145, 255)
如何用 f-string 拼接字符串
合并 f-string 与普通字符串拼接一样,可以隐式地直接拼接,或者显式地用加号 +
,或者使用 str.join
方法。
# 隐式字符串拼接 print(f"{
123}" " = " f"{
100}" " + " f"{
20}" " + " f"{
3}") # 输出:123 = 100 + 20 + 3 # 使用加号 + 的显式字符串拼接 print(f"{
12}" + " != " + f"{
13}") # 输出:12 != 13 # 使用 str.join 的字符串拼接 print("".join((f"{
13}", f"{
45}"))) # 输出:1345 print("#".join((f"{
13}", f"{
45}"))) # 输出:13#45
如何格式化 datetime 对象
F-string 也支持 datetime 对象的格式化。其过程与 str.format
格式化日期的方法很近似。请查阅官方文档中的表格获取更多所支持格式的相关信息。
import datetime now = datetime.datetime.now() ten_days_ago = now - datetime.timedelta(days=10) print(f'{
ten_days_ago:%Y-%m-%d %H:%M:%S}') # 输出:2024-08-22 16:08:07 print(f'{
now:%Y-%m-%d %H:%M:%S}') # 输出:2024-09-01 16:08:07
4.字符串模板 string template
>>> from string import Template >>> s = Template('$who likes $what') >>> s.substitute(who='tim', what='kung pao') 'tim likes kung pao' >>> d = dict(who='tim') >>> Template('Give $who $100').substitute(d) Traceback (most recent call last): ... ValueError: Invalid placeholder in string: line 1, col 11 >>> Template('$who likes $what').substitute(d) Traceback (most recent call last): ... KeyError: 'what' >>> Template('$who likes $what').safe_substitute(d) 'tim likes $what'
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/129043.html