查看原文
其他

实用!f-strings 比你想象的还要强大

Linux爱好者 2024-03-09

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 -

推荐阅读  点击标题可跳转

1、很期待!尝鲜 Python 3.11 的 5 个新特性

2、快 45%,Python 3.11 性能表现优异

3、用 Python 制作 13 个小游戏,边玩边学!(含源码)


↓推荐关注↓

「Python开发精选」分享 Python 技术文章、资源、课程、资讯。


点赞和在看就是最大的支持❤️

继续滑动看下一个

实用!f-strings 比你想象的还要强大

向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存