在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
参考:
- f-strings更多介绍:https://realpython.com/python-f-strings/