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

从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. C#从入门到放弃治疗一:初探C#世界

    C#是一款高级的面向对象语言,运行于.NET framework之上的高级程序设计语言.其语言规范和,语法和java有着惊人的类似之处.所以如果你在学习C#之前有着java的基础,你将快速地入门.当然 ...

  2. 【.NET 与树莓派】矩阵按键

    欢迎收看火星卫视,本期节目咱们严重探讨一下矩阵按键. 所谓矩阵按键,就是一个小键盘(其实一块PCB板),上面有几个 Key(开关),你不按下去的时候,电路是断开的,你按下去电路就会接通.至于说有多少个 ...

  3. 推荐几个学习Python的免费网站

    想要学好Python,只靠看Python相关的书籍是远远不够的!今天为大家分享几个实用的Python学习网站. 欢迎各位热爱Python的小伙伴进群交流:610380249群里有大佬哦,而且很热心,群 ...

  4. 【JeecgBoot】关于 jeecg-boot 的项目理解、使用心得和改进建议

    工欲善其事,必先利其器. 脚手架选型 一年前,我接到为团队落地一个快速开发脚手架的任务. 在月底这节骨眼上,时间紧,任务急,有想自己撸一个脚手架的人都赶紧把这想法收起来吧!这劳民又伤身的事咱肯定是不能 ...

  5. LVM 逻辑卷扩容

    当lv空间不够用时,就需要我们对lv进行的扩容. 扩容分两种情况:(lv的有点,支持在线扩容) VG有充足的空间,可直接对LV进行扩容: VG空间不足,需要先对VG进行扩容,然后再对LV进行扩容 这里 ...

  6. 获取Java线程转储的常用方法

    1. 线程转储简介 线程转储(Thread Dump)就是JVM中所有线程状态信息的一次快照. 线程转储一般使用文本格式, 可以将其保存到文本文件中, 然后人工查看和分析, 或者使用工具/API自动分 ...

  7. 无法获取 vmci 驱动程序版本: 句柄无效。 驱动程序 vmci.sys 版本不正确。请尝试重新安装 VMware Workstation。 打开模块DevicePowerOn电源失败。

    1.别打开电源,然后到虚拟机安装文件夹内.2.找到你的虚拟机系统文件中后缀为vmx的文件,右击用记事本或者Notepad++打开.2.搜索找到vmci0.present='TRUE',字段,把true ...

  8. vfd-cloud——一个适合练习上手的云存储网盘springboot项目(开发中)

    vfd-cloud           ​ 一个基于SpringBoot的云存储网盘项目,适合练手学习SpringBoot,用到的技术栈列到了下面.支持用户的注册登陆及修改密码,利用邮箱进行验证.支持 ...

  9. IDEA SSM后端框架入门

    SSM框架 如果对SSM一无所知,推荐先去看这本书,可以在微信读书上看. 知识点 控制器返回对象时,对象需要有getter,setter方法,才能自动转化为json数据类型. 一个服务管理者对应多个业 ...

  10. 1 flume快速入门——十分钟学会flume

    flume ## 1.1 Flume定义 Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统.Flume基于流式架构,灵活简单. 大数据框架大致分为3类: ...