Item 4: Prefer Interpolated F-Strings Over C-style Format Strings and str.format(请使用f-string格式化字符串)

在Python 3.6中,f-string是格式化字符串的一种很好的新方法。它们不仅比其他格式更易于阅读、更简洁、更不易出错,而且速度更快!

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

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

选项1:% format

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

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

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

  • 如何使用%format
>>> name = "Eric"
>>> "Hello, %s." % name
'Hello, Eric.'

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

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

为什么%format不好

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

>>> 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()  是%格式的改进。它使用普通的函数调用语法,并且可以通过__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字符串也称为“格式化的字符串文字”,是指字符串文字,f其开头有一个,花括号中包含将被其值替换的表达式。在运行时对表达式求值,然后使用__format__协议对其进行格式化。与往常一样,当您想了解更多信息时,Python文档是更好的。
简单语法
语法与您使用的语法相似,str.format()但较为冗长。看看这是多么容易阅读:

>>> 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字符串是在运行时求值的,因此您可以在其中放入任何和所有有效的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字符串的类创建的对象。想象一下您有以下类:

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__(),但是__repr__()如果您包含conversion标志,则可以确保使用它们!r:

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

您可以使用多行字符串:

>>> 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-字符串可能也代表“快”。

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

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

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

>>> import timeit
>>> timeit.timeit("""name = "Eric"
... age = 74
... '%s is %s.' % (name, age)""", number = 10000)
0.003324444866599663

>>> timeit.timeit("""name = "Eric"
... age = 74
... f'{name} is {age}.'""", number = 10000)
0.0024820892040722242

参考:

  1. f-strings更多介绍:https://realpython.com/python-f-strings/
posted @ 2020-06-02 22:24  码上的生活  阅读(350)  评论(0编辑  收藏  举报