实用!f-strings 比你想象的还要强大
The following article is from Python开发者 Author 南风草木香
【导语】:本文介绍了“格式化字符串常量”f-strings
一些不常见的特性,包括:格式化日期和时间、同时打印变量名和变量值等,嵌套使用f-strings
等,此外与其他格式化字符串的方法相比,f-strings
的速度更快,因此,学习这些新特性有助于开发者更好地处理字符串。
简介
f-strings,也称为格式化字符串常量(formatted string literals),是Python3.6引入的一种字符串格式化方法,它的使用方式为f'xxx',只需将要替换的字段放到{}
中,就可以格式化字符串了。相信很多读者已经使用过f-strings了。然而许多好用的特性你可能还未使用过,我们来一起学习下。Python开发者之前还分享一篇包含73个f-string例子的文章,建议收藏一起阅读。
1. 格式化日期和时间
用f-strings格式化数字很常见,但你知道f-strings也可以用来格式化日期和时间戳字符串吗?
import datetime
today = datetime.datetime.today()
print(f"{today:%Y-%m-%d}")
# 2022-07-04
print(f"{today:%Y}")
# 2022
f-strings可以格式化日期和时间,它与datetime.strftime
的功能一样。同时,所有底层C实现所支持的格式,在Python的strftime中也可以使用。但在不同的平台上,使用方式可能有所不同。你可以在Linux manpages[1]上查阅相关信息,例如%F
相当于%Y-%m-%d
,%T
相当于%H:%M:%S
,此外%x
和%X
分别是设置地区首选的日期和时间格式。
2. 变量名和调试
f-strings最近新增的一个特性是可以同时打印变量名和变量值(Python 3.8及之后的版本均可使用):
x = 10
y = 25
print(f"x = {x}, y = {y}")
# x = 10, y = 25
print(f"{x = }, {y = }") # 更方便! (3.8+)
# x = 10, y = 25
print(f"{x = :.3f}")
# x = 10.000
该特性被称为“调试”,可以与其他修饰符结合使用。它还能检测到空格,因此f"[x =]和f"[x =]"会产生不同的结果。
3. __repr__ and __str__
当输出类的实例时,默认使用的是类的__str__
方法。如果我们想将默认方法改为__repr__
,可以使用!r
进行转换。
class User:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def __str__(self):
return f"{self.first_name} {self.last_name}"
def __repr__(self):
return f"User's name is: {self.first_name} {self.last_name}"
user = User("John", "Doe")
print(f"{user}")
# John Doe
print(f"{user!r}")
# User's name is: John Doe
我们也可以调用f-string内部的repr(some_var)
方法,但直接使用转化标志显然更加方便。
4. f-strings的性能更优
通常新特性和语法糖的提出都是以牺牲性能为代价的,但f-strings成功做到了两者兼顾:
# python -m timeit -s 'x, y = "Hello", "World"' 'f"{x} {y}"'
from string import Template
x, y = "Hello", "World"
print(f"{x} {y}") # 39.6 纳秒 - 最快!
print(x + " " + y) # 43.5 纳秒
print(" ".join((x, y))) # 58.1 纳秒
print("%s %s" % (x, y)) # 103 纳秒
print("{} {}".format(x, y)) # 141 纳秒
print(Template("$x $y").substitute(x=x, y=y)) # 1.24 微秒 - 最慢!
以上所有示例的耗费时间均是用timeit模块测试的,例如我们想测试f-strings,就可以这样做:python -m timeit -s 'x, y = "Hello", "World"' 'f"{x} {y}"'
,由测试结果可知,f-strings是所有方法中最快的,因此非常推荐使用该方法。
5. 格式化标准
f-strings支持Python的格式化标准[2],所以我们可以在修饰符中进行多种格式化操作:
text = "hello world"
# 文本居中:
print(f"{text:^15}")
# ' hello world '
number = 1234567890
# 加入分隔符
print(f"{number:,}")
# 1,234,567,890
number = 123
# 在起始位置补0
print(f"{number:08}")
# 00000123
通过使用Python的格式化功能,不仅可以格式化数字和日期,还可以对齐或居中文本,在字符串前面添加0或者空格,添加分隔符。这些特性也可以在其他格式化方法中使用。
6. f-strings的嵌套使用
如果f-strings的基本功能不能满足你的需求,你还可以将其嵌套使用,假如我们想在一个数字前加上$
符号,可以这样做:
number = 254.3463
print(f"{f'${number:.3f}':>10s}")
# ' $254.346'
如果你需要在格式符中加入变量,也可以使用嵌套的f-strings。这样f-string的可读性也更强:
import decimal
width = 8
precision = 3
value = decimal.Decimal("42.12345")
print(f"output: {value:{width}.{precision}}")
# 'output: 42.1'
7. 分情况格式化字符串
在嵌套使用f-strings的基础上,我们还可以在其内部使用三元条件操作符:
import decimal
value = decimal.Decimal("42.12345")
print(f'Result: {value:{"4.3" if value < 100 else "8.3"}}')
# Result: 42.1
value = decimal.Decimal("142.12345")
print(f'Result: {value:{"4.2" if value < 100 else "8.3"}}')
# Result: 142
8. Lambda表达式
我们也可以在f-strings中使用lambda表达式,在如下的例子中,我们需要把lambda表达式放到括号中,否则:
会被f-strings当作字符串:
print(f"{(lambda x: x**2)(3)}")
# 9
结论
通过前面的使用,我们可以看到f-strings还有许多好用的特性,然而许多读者可能没有用过这些特性。因此在平时的学习中,我们还可以查看其他模块的官方文档,也许你会发现一些有趣的东西。
参考资料
[1]Linux manpages: https://manpages.debian.org/bullseye/manpages-dev/strftime.3.en.html
[2]格式化标准: https://docs.python.org/3/library/string.html#formatspec
[3]参考原文: https://martinheinz.dev/blog/70
- EOF -
↓推荐关注↓
「Python开发精选」分享 Python 技术文章、资源、课程、资讯。
点赞和在看就是最大的支持❤️