Python 四种字符串格式化方式
格式化(formatting)是指把数据填写到预先定义的文本模板里面,形成一条用户可读的消息,并把这条消息保存成字符串的过程。
% 格式化
Python 里面最常用的字符串格式化方式是采用 % 格式化操作符。
这个操作符左边的文本模板叫作格式字符串(format string),我们可以在操作符右边写上某个值或者由多个值所构成的元组(tuple),用来替换格式字符串里的相关符号。
例如,下面这段代码通过 % 操作符把难以阅读的二进制和十六进制数值,显示成十进制的形式。
a = 0b10111011
b = 0xc5f
print('Binary is %d, hex is %d' % (a, b))
# >>>
# Binary is 187, hex is 3167
格式字符串里面可以出现 %d 这样的格式说明符,这些说明符的意思是,% 右边的对应数值会以这样的格式来替换这一部分内容。格式说明符的写法来自 C 语言的 printf 函数,所以,常见的 printf 选项都可以当成 Python 的格式说明符来用,例如 %s、%x、%f 等,此外还可以控制小数点的位值,并指定填充与对齐方式。
但是,C 风格的格式字符串,在 Python 里有四个缺点。
第一个缺点是,如果 % 右侧那个元组里面的值在类型或顺序上有变化,那么程序可能会因为转换类型时发生不兼容问题而出现错误。例如一个简单的例子:
key = 'my_var'
value = 1.234
formatted = '%-10s = %.2f' % (key, value)
print(formatted)
# >>>
# my_var = 1.23
但如果把 key 跟 value 互换位置,那么程序就会在运行时出现异常。
reordered_tuple = '%-10s = %.2f' % (value, key)
# >>>
# TypeError: must be real number, not str
如果 % 右侧的写法不变,但左侧那个格式字符串里面的两个说明符对调了顺序,那么程序同样会发生这个错误。
reordered_string = '%.2f = %-10s' % (key, value)
# >>>
# TypeError: must be real number, not str
要想避免这种问题,必须经常检查 % 操作符左右两侧的写法是否相互兼容。
第二个缺点是,在填充模板之前,经常要先对准备填写进去的这个值稍微做一些处理,但这样一来,整个表达式可能就会写得很长,让人觉得比较混乱。
下面这段代码用来罗列厨房里的各种食材,现在的这种写法并没有对填入格式字符串里面的那三个值(也就是食材的编号 i、食材的名称 item,以及食材的数量 count)预先做出调整。
pantry = [
('avocados', 1.25),
('bananas', 2.5),
('cherries', 15),
]
for i, (item, count) in enumerate(pantry):
print('#%d: %-10s = %.2f' % (i, item, count))
# >>>
# #0: avocados = 1.25
# #1: bananas = 2.50
# #2: cherries = 15.00
如果想让打印出来的信息更好懂,那可能得把这几个值稍微调整一下,但是调整之后,% 操作符右侧的那个三元组就特别长,所以需要多行拆分才能写得下,这会影响程序的可读性。
for i, (item, count) in enumerate(pantry):
print('#%d: %-10s = %d' % (
i + 1,
item.title(),
round(count)))
# >>>
# #1: Avocados = 1
# #2: Bananas = 2
# #3: Cherries = 15
第三个缺点是,如果想用同一个值来填充格式字符串里的多个位置,那么必须在 % 操作符右侧的元组中相应地多次重复该值。
template = '%s loves food. See %s cook.'
name =