Python 3的F字符串:改进的字符串格式语法

2021-01-21 04:35:04

立即观看本教程有一个由Real Python团队创建的相关视频课程。与书面教程一起观看,以加深您的理解:Python 3的f字符串:改进的字符串格式语法

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

到本文结尾,您将了解如何以及为什么今天开始使用f弦。

但是首先,这就是弦乐演奏之前的生活,那是当你不得不在雪地上双向步行上学的时候。

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

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

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

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

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

为了插入多个变量,必须使用这些变量的元组。这样做的方法如下:

>>> >>>名称=" Eric" >>>年龄= 74>> "您好,%s。您是%s。" %(name,age)' Hello Eric。你今年74岁。

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

>>> >>> first_name =" Eric" >>> last_name =" Idle" >>>年龄= 74>>专业="喜剧演员" >>>隶属关系=" Monty Python" >>> "您好,%s%s。你是%s。您是%s。您是%s的成员。" %(first_name,last_name,年龄,专业,从属关系)'您好,Eric Idle。你74岁。你是喜剧演员。您是Monty Python的成员。'

不幸的是,这种格式不好用,因为它太冗长并会导致错误,例如无法正确显示元组或字典。幸运的是,还有更美好的日子。

Python 2.6中引入了这种完成工作的新方法。您可以查看新Python字符串格式技术指南以获得更多信息。

str.format()是%格式的改进。它使用普通的函数调用语法,并且可以通过将__format __()方法转换为要转换为字符串的对象来进行扩展。

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

>>> >>>人= {'名字' :' Eric' ,'年龄' :74}>> "您好,{name}。您是{age}。" 。格式(姓名=人[' name'],年龄=人[' age'])' Hello,Eric。你今年74岁。

>>> >>>人= {'名字' :' Eric' ,'年龄' :74}>> "您好,{name}。您是{age}。" 。格式(**人)'你好,埃里克。你今年74岁。

与%-formatting相比,str.format()绝对是升级,但并不是所有的玫瑰和阳光。

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

>>> >>> first_name =" Eric" >>> last_name =" Idle" >>>年龄= 74>>专业="喜剧演员" >>>隶属关系=" Monty Python" >>> print(("您好,{first_name} {last_name}。您是{age}。" +>>>"您是{profession}。您是{ }(")\>>>格式(first_name = first_name,last_name = last_name,age =年龄,\ gt;>>>>>>专业=职业,隶属关系=隶属关系))'您好,埃里克·艾德(Eric Idle)。你74岁。你是喜剧演员。您是Monty Python的成员。'

如果您有要在字典中传递给.format()的变量,则可以只用.format(** some_dict)解压缩并按字符串中的键引用值,但必须有一个更好的方法做到这一点的方法。

好消息是F弦乐在这里挽救了一天。他们切片!他们骰子!他们做朱莉安薯条!好的,它们什么都不做,但是它们确实使格式化更容易。他们加入了Python 3.6。您可以在2015年8月由Eric V.Smith撰写的PEP 498中阅读所有内容。

f字符串也称为“格式化字符串文字”,是在开头带有f且花括号包含将被其值替换的表达式的字符串文字。在运行时对表达式求值,然后使用__format__协议对其进行格式化。与往常一样,当您想了解更多信息时,Python文档是您的朋友。

该语法与您用于str.format()的语法相似,但较为冗长。看看这是多么容易阅读:

>>> >>>名称=" Eric" >>>年龄= 74>> f"您好,{name}。您是{age}。" '你好,埃里克。你今年74岁。

你喜欢f弦吗?希望在本文结尾处,您将回答>>> F"是!"。

由于f字符串是在运行时求值的,因此您可以在其中放入任何和所有有效的Python表达式。这使您可以做一些漂亮的事情。

>>> >>> def to_lowercase(input):...返回输入。下()>>名称=" Eric Idle" >>> f" {to_lowercase(name)}很有趣。" “ eric闲置很有趣。”

您甚至可以使用从带有f字符串的类创建的对象。想象一下您有以下课程:

喜剧演员类:def __init __(self,first_name,last_name,age):self。 first_name = first_name self。 last_name = last_name self。 age = age def __str__(self):返回f" {自我。 first_name} {自我。 last_name}是{self。年龄}。" def __repr__(self):返回f" {自我。 first_name} {自我。 last_name}是{self。年龄}。惊喜!"

__str __()和__repr __()方法处理对象如何以字符串形式显示,因此您需要确保在类定义中至少包括这些方法之一。如果必须选择一个,请使用__repr __(),因为它可以代替__str __()使用。

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

默认情况下,f字符串将使用__str __(),但是如果包含转换标志!r,则可以确保它们使用__repr __()。

如果您想阅读一些导致f字符串支持完整Python表达式的对话,则可以在此处进行。

>>> >>>名称=" Eric" >>>专业="喜剧演员" >>>隶属关系=" Monty Python" >>> message =(... f" Hi {name}。" ... f" You are a {career}。" ... f" You are in {隶属关系}。" ...)>>消息' Hi Eric。你是喜剧演员。您在Monty Python中。

但是请记住,您需要在多行字符串的每一行前面放置一个f。以下代码无效:

>>> >>> message =(... f" Hi {name}。" ..."您是{职业}。" ..."您处于{隶属关系}。" ...)>>消息' Hi Eric。您是{职业}。您当时处于{affiliation}。'

如果您没有在每行的前面都加上f,那么您将只有普通的,老式的,花园风格的琴弦,而不是闪亮的,新颖的,精美的f琴弦。

如果要将字符串分布在多行中,还可以选择使用\来转义返回值:

>>> >>> message = f" Hi {name}。 " \ ... f"您是{职业}。 " \ ... f"您处于{隶属关系}。" ...>>>消息' Hi Eric。你是喜剧演员。您在Monty Python中。

>>> >>>消息= f""" ...您好{name}。 ...您是{职业}。 ...您处于{隶属关系}。 ...""" ...>>>消息' \ n埃里克(Eric),您好。\ n您是喜剧演员。\ n您曾在Monty Python中工作。\ n'

f字符串比%-formatting和str.format()都快。如您所见,f字符串是在运行时求值的表达式,而不是常量值。以下是这些文档的摘录:

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

在运行时,大括号内的表达式在其自己的范围内求值,然后与f字符串的字符串文字部分放在一起。然后返回结果字符串。仅此而已。

>>> >>>导入时间>>> timeit。 timeit("" name =" Eric" ... age = 74 ...'%s是%s。'%(name ,age)""&#34 ;,数字= 10000)0.003324444866599663

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

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

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

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

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

>>> >>>喜剧演员= {'名字' :' Eric Idle' ,'年龄' :74}>> f"喜剧演员是{喜剧演员[' name' ]},年龄{喜剧演员[' age' ]}。"喜剧演员是埃里克·艾德(Eric Idle),现年74岁。

>>> >>>喜剧演员= {'名字' :' Eric Idle' ,'年龄' :74}>> f'喜剧演员是{喜剧演员[' name' ]},年龄{喜剧演员[' age' ]}。'档案"< stdin>&#34 ;,第1行f'喜剧演员是{喜剧演员[' name' ]},年龄{喜剧演员[' age' ]}。' ^ SyntaxError:语法无效

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

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

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

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

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

>>> >>> f" {\" Eric Idle \" }"文件"< stdin>&#34 ;,第1行f" {\" Eric Idle \" }" ^ SyntaxError:f字符串表达式部分不能包含反斜杠

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

表达式中不应包含使用#符号的注释。您会收到语法错误:

>>> >>> f" Eric是{2 * 37#天哪! }"文件"< stdin>&#34 ;,第1行f" Eric是{2 * 37#我的天哪! }" ^ SyntaxError:f字符串表达式部分不能包含'#'

您仍然可以使用旧的格式化字符串的方法,但是使用f字符串,您现在有了更简洁,易读和方便的方法,既快捷又不易出错。如果您尚未进行切换,那么使用f字符串简化生活是开始使用Python 3.6的重要原因。 (如果您仍在使用Python 2,请不要忘记2020年即将到来!)

根据Python Zen的说法,当您需要决定如何做某事时,那么“这应该是一种(最好只有一种)显而易见的方式。”尽管f字符串不是格式化字符串的唯一可能方法,但是它们很适合成为完成工作的一种明显方式。

如果您想阅读有关字符串插值的扩展讨论,请查看PEP502。此外,PEP 536草案对f字符串的未来有更多的想法。

立即观看本教程有一个由Real Python团队创建的相关视频课程。与书面教程一起观看,以加深您的理解:Python 3的f字符串:改进的字符串格式语法

简短说明每两天就会向您的收件箱发送一个可爱的Python Trick。从来没有垃圾邮件。随时退订。由Real Python团队策划。