Python中format、%与f-string的区别

Python 2.5之前,我们使用的是老式格式化输出:%s。从Python 3.0开始起(Python 2.6同期发布),同时支持两个版本的格式化,多出来的一个新版本就是利用format()函数,进行格式化输出。Python 3.6又引入了新的字符串格式化方式 f-strings

%

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

字符串中嵌入多个变量,则必须使用元组:

>>> name = "Tom"
>>> age = 18
>>> "Hello, %s. You are %s." % (name, age)
'Hello Tom. You are 18.'

这种格式化方式的主要问题是过于繁琐,容易出错,不能正确格式化元组与字典。


str.format()

str.format()方式是对 % 方式的一次改进。用户可以通过修改对象的 __format__() 方法来自定义格式化方式。

通过大括号,可以在字符串中嵌入变量:

>>> "Hello, {}. You are {}.".format(name, age)
'Hello, Tom. You are 18.'

也可以指定变量的引用顺序:

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

或者直接使用变量名称:

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

引用字典时,可以用**操作符进行字典拆包:

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

str.format()% 格式化方式的一次升级,但如果在较长的字符串中嵌入多个变量,依然会显得繁琐。

f-String

f-strings 也称作“格式化的字符串字面量”,它是一个带有 f 前缀的字符串,通过大括号嵌入所需的 Python 表达式,这些表达式的具体值是在运行时确定的,背后依赖的也是嵌入对象的 __format()__ 接口。

f-strings 的句法类似于str.format(),但更简洁:

>>> name = "Tom"
>>> age = 18
>>> f"Hello, {name}. You are {age}."
'Hello, Tom. You are 18.'

tips:前缀f也可以使用大写的F

直接使用计算式:

>>> f"{2 * 9}"
'18'

调用函数:

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

调用对象方法:

>>> f"{name.lower()} is funny."
'Tom 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("Walter", "White", "19")
>>> f"{new_comedian}"
'Walter White is 19.'

__str__()方法与__repr__()方法用于处理对象的字符串显示方式,我们有必要至少定义其中一个。如果必须二选一的话,建议使用__repr__(),在__str__()方法没有定义的情况下,解释器会自动调用__repr__()方法。

__str__()方法返回的是对象的非正式字符串表示,主要考虑可读性,而__repr__()方法返回的是对象的正式字符串表示,主要考虑精确性。调用这两个函数时,比较推荐的方式是直接使用内置函数str()repr()

f-strings 会默认调用对象的__str__()方法,如果要强制使用__repr__()方法,则可以在变量之后加上转换标志!r

f-strings 比 % 和 str.format()格式化在速度上都要快。

使用 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.'

字典

关于引号的问题,需要注意表达式中的字典取值。如果外部字符串使用的是单引号,字典取值就应该用双引号。

以下代码是可以工作的:

>>> 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"{{74}}"
'{74}'

注意,使用三次大括号并不会给你两个大括号:

>>> f"{{{74}}}"
'{74}'

当然,如果使用四次,就可以给你两个大括号了:

>>> f"{{{{74}}}}"
'{{74}}'

反斜线符号

如之前所见,我们可以在 f-strings 的字符串部分通过反斜线对一些字符进行转义。

但是,在表达式中的反斜线是没有转义效果的:

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

有需要时,可以提前定义一个变量来绕过这种限制:

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

行内注释

f-strings 中不应包括带 # 号的注释,否则会导致句法错误:

>>> 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://realpython.com/python-f-strings/

https://zhuanlan.zhihu.com/p/90439125

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值