最近也在一个视频网站的爬虫,项目已经完成,中间有不少需要总结的经验。

从Python 3.6开始,f-Strings是格式化字符串的一种很棒的新方法。与其他格式化方式相比,它们不仅更具可读性,更简洁且不易出错,而且速度更快!

Python中的“老式”字符串格式化

在Python 3.6之前,你有两种主要的方式,将Python表达式嵌入到字符串文字中进行格式化:%-formatting和str.format()。本文将首先介绍如何使用它们以及它们的局限性。

选项#1:%-formatting

这是Python格式化的OG,从一开始就存在于语言中。你可以在Python文档中阅读更多内容。请记住,文档不建议使用%格式,其中包含以下注意事项:

“这里描述的格式化操作表现出各种古怪问题,导致许多错误(例如未能正确显示元组和字典)。

使用较新的格式化字符串文字或str.format()方法有助于避免这些错误。这些替代方案还提供了更强大,灵活和可扩展的文本格式设置方法。”

如何使用 %-formatting

字符串对象具有使用该%运算符的内置操作,可用于格式化字符串。这是实际的情况:

>>> name = "Eric"
>>> "Hello, %s." % name
'Hello, Eric.'

为了插入多个变量,你必须使用这些变量的元组。这是你要执行的操作:

>>> name = "Eric"
>>> age = 74
>>> "Hello, %s. You are %s." % (name, age)
'Hello Eric. You are 74.'

为什么%-formatting不好

上面看到的代码示例具有足够的可读性。但是,一旦开始使用多个参数和更长的字符串,你的代码将很快变得不那么易读。看起来有些混乱:

>>> first_name = "Eric"
>>> last_name = "Idle"
>>> age = 74
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> "Hello, %s %s. You are %s. You are a %s. You were a member of %s." % (first_name, last_name, age, profession, affiliation)
'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

这种格式不是很好,因为它很冗长并且会导致错误,例如不能正确显示元组或字典。

选项#2:str.format()

Python 2.6中引入了这种完成工作的新方法。你可以查看《 Python字符串格式新手指南》以获取更多信息。

如何使用str.format()

str.format() 是对 %-formatting 的改进。它使用正常的函数调用语法,并且可以通过 format() 方法对被转换为字符串的对象进行扩展。

使用str.format(),替换字段用花括号标记:

>>> "Hello, {}. You are {}.".format(name, age)
'Hello, Eric. You are 74.'

你可以通过引用变量的索引以任何顺序引用它们:

>>> "Hello, {1}. You are {0}.".format(age, name)
'Hello, Eric. You are 74.'

但是,如果你插入变量名,则会获得以下额外的好处:能够传递对象,然后在花括号之间引用参数和方法:

>>> person = {'name': 'Eric', 'age': 74}
>>> "Hello, {name}. You are {age}.".format(name=person['name'], age=person['age'])
'Hello, Eric. You are 74.'

你也可以使用**字典来完成这个巧妙的技巧:

>>> person = {'name': 'Eric', 'age': 74}
>>> "Hello, {name}. You are {age}.".format(**person)
'Hello, Eric. You are 74.'

str.format() 与%格式相比绝对是一个升级。

为什么 str.format() 不好

使用str.format()代码比使用 %-formatting 的代码更容易阅读,但是str.format()当你处理多个参数和更长的字符串时,代码仍然很冗长。看看这个:

>>> first_name = "Eric"
>>> last_name = "Idle"
>>> age = 74
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> print(("Hello, {first_name} {last_name}. You are {age}. " +
>>> "You are a {profession}. You were a member of {affiliation}.") \
>>> .format(first_name=first_name, last_name=last_name, age=age, \
>>> profession=profession, affiliation=affiliation))
'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

如果你要.format()在字典中传递变量,则可以将其解压缩.format(**some_dict)并按字符串中的键引用值,但是必须有一种更好的方法来执行此操作。

f-Strings表达式:Python中一种增强的格式化字符串的新方法

f-Strings 表达式使格式化更容易。他们加入了Python 3.6。你可以在2015年8月由Eric V.Smith撰写的PEP 498中阅读全部内容。

f-Strings 也称为“格式化的字符串文字”,是一种字符串文字,其开头是 f,后面是大括号,其中包含将被替换为其值的表达式。这些表达式在运行时被评估,然后使用 "format" 协议进行格式化。当你想了解更多信息时,Python文档是你的朋友。

下面是一些 f-strings 可以让你的生活更轻松的方法。

简单语法

看看这是多么容易阅读:

>>> name = "Eric"
>>> age = 74
>>> f"Hello, {name}. You are {age}."
'Hello, Eric. You are 74.'

使用大写字母也是有效的F

>>> F"Hello, {name}. You are {age}."
'Hello, Eric. You are 74.'

任意表达

因为 f-strings 在运行时被评估,所以您可以在其中放入任何和所有有效的 Python 表达式。

你可以做一些非常简单的事情,例如:

>>> f"{2 * 37}"
'74'

但是你也可以调用函数。这是一个例子:

>>> def to_lowercase(input):
... return input.lower() >>> name = "Eric Idle"
>>> f"{to_lowercase(name)} is funny."
'eric idle is funny.'

你还可以选择直接调用方法:

>>> f"{name.lower()} is funny."
'eric idle is funny.'

你甚至可以使用从带有f-strings的类创建的对象:

class Comedian:
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age def __str__(self):
return f"{self.first_name} {self.last_name} is {self.age}." def __repr__(self):
return f"{self.first_name} {self.last_name} is {self.age}. Surprise!"

你执行以下操作:

>>> new_comedian = Comedian("Eric", "Idle", "74")
>>> f"{new_comedian}"
'Eric Idle is 74.'

__str__()__repr__()方法处理对象是如何呈现为字符串,所以你需要确保你包括你的类定义这些方法的至少一个。如果你必须选择一个,请继续使用,__repr__()因为它可以代替使用__str__()

返回的__str__()字符串是对象的非正式字符串表示形式。返回的字符串__repr__()是正式表示形式,应明确。调用str()repr()比直接使用__str__()和更可取__repr__()

默认情况下,f字符串将使用__str__(),但是如果你加入转换标志 !r,你可以确保它们使用__repr__()

>>> f"{new_comedian}"
'Eric Idle is 74.'
>>> f"{new_comedian!r}"
'Eric Idle is 74. Surprise!'

如果你想阅读一些导致 f-Strings 支持完整Python表达式的对话,则可以在此处进行

多行f-Strings

你可以使用多行字符串:

>>> name = "Eric"
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> message = (
... f"Hi {name}. "
... f"You are a {profession}. "
... f"You were in {affiliation}."
... )
>>> message
'Hi Eric. You are a comedian. You were in Monty Python.'

但是请记住,你需要在多行字符串的每一行前面放一个f。以下代码不起作用:

>>> message = (
... f"Hi {name}. "
... "You are a {profession}. "
... "You were in {affiliation}."
... )
>>> message
'Hi Eric. You are a {profession}. You were in {affiliation}.'

如果你没有f在每行的前面都放一个,那么你将只有规则的,古老的,花园风格的琴弦,而不是闪亮的,新颖的,奇特的f琴弦。

如果你想将字符串分布在多行中,则还可以选择使用-转义字符 \

>>> message = f"Hi {name}. " \
... f"You are a {profession}. " \
... f"You were in {affiliation}."
...
>>> message
'Hi Eric. You are a comedian. You were in Monty Python.'

但是,如果使用以下方法,将会发生以下情况"""

>>> message = f"""
... Hi {name}.
... You are a {profession}.
... You were in {affiliation}.
... """
...
>>> message
'\n Hi Eric.\n You are a comedian.\n You were in Monty Python.\n'

阅读PEP 8中的缩进准则。

速度

f-Strings 比 %-formatting 和 str.format() 都要快。如你所见,f-Strings 是在运行时求值的表达式,而不是常量值。以下摘自文档:

“f-Strings 提供了一种使用最小语法在字符串文字中嵌入表达式的方法。应当注意,f-Strings 实际上是在运行时评估的表达式,而不是常数。在Python源代码中,f-Strings 是文字字符串,前缀为f,其中花括号内包含表达式。这些表达式将替换为其值。” (来源

在运行时,大括号内的表达式在其自己的范围内求值,然后与 f-Strings 的字符串文字部分放在一起。然后返回结果字符串。这就是全部。

这是速度比较:

>>> import timeit
>>> timeit.timeit("""name = "Eric"
... age = 74
... '%s is %s.' % (name, age)""", number = 10000)
0.003324444866599663
>>> timeit.timeit("""name = "Eric"
... age = 74
... '{} is {}.'.format(name, age)""", number = 10000)
0.004242089427570761
>>> timeit.timeit("""name = "Eric"
... age = 74
... f'{name} is {age}.'""", number = 10000)
0.0024820892040722242

如你所见,f-Strings 最快。

但是,情况并非总是如此。首次实施时,它们存在一些速度问题,需要使其速度比更快str.format()。引入了特殊的BUILD_STRING操作码

Python f-Strings:细节

既然你已经了解了为什么 f-Strings 很棒,我相信你一定要开始使用 f-Strings 。当你冒险进入这个勇敢的新世界时,请牢记以下一些细节。

引号

你可以在表达式内使用各种类型的引号。只要确保你没有在表达式中使用与 f-Strings 相同的引号即可。

该代码将起作用:

>>> f"{'Eric Idle'}"
'Eric Idle'

该代码也将起作用:

>>> f'{"Eric Idle"}'
'Eric Idle'

你还可以使用三引号:

>>> f"""Eric Idle"""
'Eric Idle'
>>> f'''Eric Idle'''
'Eric Idle'

如果发现需要在字符串的内部和外部使用相同类型的引号,则可以使用 \ 命令进行转义:

>>> f"The \"comedian\" is {name}, aged {age}."
'The "comedian" is Eric Idle, aged 74.'

字典

说到引号,使用字典时要当心。如果要对字典的键使用单引号,请记住确保对包含键的 f-Strings 使用双引号。

这将起作用:

>>> comedian = {'name': 'Eric Idle', 'age': 74}
>>> f"The comedian is {comedian['name']}, aged {comedian['age']}."
The comedian is Eric Idle, aged 74.

但这是一个语法错误的情况:

>>> comedian = {'name': 'Eric Idle', 'age': 74}
>>> f'The comedian is {comedian['name']}, aged {comedian['age']}.'
File "<stdin>", line 1
f'The comedian is {comedian['name']}, aged {comedian['age']}.'
^
SyntaxError: invalid syntax

如果在字典键周围使用与在f字符串外部相同的引号类型,则第一个字典键开头的引号将被解释为字符串的结尾。

大括号

为了使大括号出现在字符串中,必须使用双大括号:

>>> f"{{70 + 4}}"
'{70 + 4}'

请注意,使用三重花括号将导致字符串中只有一个大括号:

>>> f"{{{70 + 4}}}"
'{74}'

但是,如果使用的括号多于三个,则可以显示更多的括号:

>>> f"{{{{70 + 4}}}}"
'{{70 + 4}}'

反斜杠

如前所述,你可以在f-string的字符串部分使用反斜杠转义。但是,你不能在f-string的表达式部分使用反斜杠转义:

>>> f"{\"Eric Idle\"}"
File "<stdin>", line 1
f"{\"Eric Idle\"}"
^
SyntaxError: f-string expression part cannot include a backslash

你可以通过预先计算表达式并在f字符串中使用结果来解决此问题:

>>> name = "Eric Idle"
>>> f"{name}"
'Eric Idle'

内部注释

表达式中不应包含使用该 # 符号的注释。下面代码,你会看到语法错误:

>>> f"Eric is {2 * 37 #Oh my!}."
File "<stdin>", line 1
f"Eric is {2 * 37 #Oh my!}."
^
SyntaxError: f-string expression part cannot include '#'

总结

字符串格式化方法在很多项目里面都能用到,实用价值很高。

订阅继续关注,以后会收到更多有趣的文章。

欢迎关注我的个人网站https://www.bianchengvip.com/

本文为“一个火星程序员”原创文章,转载请标明出处

Python 3的f-Strings:增强的字符串格式语法(指南)的更多相关文章

  1. RMQ 字符串 F. Strings and Queries

    F. Strings and Queries time limit per test 2.5 s memory limit per test 256 MB input standard input o ...

  2. Python中使用f字符串进行字符串格式化的方法

    在<第3.10节 Python强大的字符串格式化新功能:使用format字符串格式化>介绍了使用format进行字符串格式化的方法,在Python 3.6中,如果格式化字符串中的关键字参数 ...

  3. Python字符串格式方式 %s format()

    p.p1 { margin: 0; font: 12px ".PingFang SC" } p.p2 { margin: 0; font: 12px "Helvetica ...

  4. Python列表、元组、字典和字符串的常用函数

    Python列表.元组.字典和字符串的常用函数 一.列表方法 1.ls.extend(object) 向列表ls中插入object中的每个元素,object可以是字符串,元组和列表(字符串“abc”中 ...

  5. Python第三天 序列 数据类型 数值 字符串 列表 元组 字典

    Python第三天 序列  数据类型  数值  字符串  列表  元组  字典 数据类型数值字符串列表元组字典 序列序列:字符串.列表.元组序列的两个主要特点是索引操作符和切片操作符- 索引操作符让我 ...

  6. python中的printf:%号拼接字符串和format函数

    在C语言中,我们使用printf("%s","hello")这种形式进行字符串的拼接 在python中,进行这样的拼接有两种实现方式,分别是%号拼接以及使用fo ...

  7. Python中使用%还是format来格式化字符串?

    Python中应该使用%还是format来格式化字符串?   %还是format Python中格式化字符串目前有两种阵营:%和format,我们应该选择哪种呢? 自从Python2.6引入了form ...

  8. Python学习笔记(四):字符串的学习

    总结的内容: 1.字符串常用的方法 2.Python字符串格式化 3.Python字符串转义字 字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 创建字符 ...

  9. Python 极简教程(八)字符串 str

    由于字符串过于重要,请认真看完并保证所有代码都至少敲过一遍. 对于字符串,前面在数据类型中已经提到过.但是由于字符串类型太过于常用,Python 中提供了非常多的关于字符串的操作.而我们在实际编码过程 ...

随机推荐

  1. ctfhub技能树—文件上传—文件头检查

    打开靶机 尝试上传一个php文件 抓包修改 放包 制作图片马 上传图片马,并修改文件类型为png 测试连接 查找flag 成功拿到flag

  2. 使用SimpleUpdater实现现有程序升级功能

    项目:https://github.com/iccfish/FSLib.App.SimpleUpdater C/S程式一般需要部署在多台机器上,如果程式有变动,需要一台一台重新安装,相当麻烦,如果我们 ...

  3. 1.2V转3.3V芯片电路图,超简电路

    镍氢可充电电池1.2V转成3.3V的电路和电子产品很多,在实际适用中,即使是两节镍氢电池串联供电也是会有供电电压下降和不稳定的影响,这是因为电池电量减少,而导致电池的电压也是会随着降低. 一般情况下, ...

  4. Java SPI机制详解

    Java SPI机制详解 1.什么是SPI? SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.SPI是一种动态替换发现的机制, 比如有个 ...

  5. error out of table range

    .

  6. 从零搭建TypeScript与React开发环境

    前言 平时进行开发大多数是基于vue-cli或者create-react-app等官方或者公司内部搭建的脚手架.   我们业务仔做的最多就是npm i和npm run dev或者npm start,然 ...

  7. 使用 Tye 辅助开发 k8s 应用竟如此简单(一)

    最近正巧在进行 Newbe.Claptrap 新版本的开发,其中使用到了 Tye 来辅助 k8s 应用的开发.该系列我们就来简单了解一下其用法. Newbe.Claptrap 是一个用于轻松应对并发问 ...

  8. PowerBI官方文档

    Excel 帮助和学习 - Microsoft 支持https://support.microsoft.com/zh-cn/excel Power Query M 公式语言引用 - PowerQuer ...

  9. Flutter环境搭建遇坑小结(一)

    对flutter的了解与开发也有一段时间了,总的来说,搭建开发环境遇到的各种坑也是很多,尤其对于初次接触Android开发的人员来说 一.flutter运行提示Running Gradle task ...

  10. Django(静态文件or路由)

    静态文件 在开发中同创会使用到 css,js,img等静态文件,这里带大家简单的介绍一下django如何处理静态页面, 配置 setting.py文件 STATIC_URL = '/static/' ...