python里的字符串格式化通常有三种方法,下面对每个方法做一个说明和比较。
1. 使用%格式化操作符
使用%格式化操作符,如下:
key = "my_var"
value = 1.234
formatted = "%s = %f" % (key, value)
print(formatted)
# my_var = 1.234000
格式化字符串里面的%s 和%d等这样的格式说明符,意思是字符串后面的% 后的元组里的内容会替换字符串里的说明符,比如上述例子,key替换了%s,value替换了%d。
具体操作符里的%s和%d什么意思不了解的,可看文末扩展内容补充,也可自行查找资料学习。
这个方法是新手使用比较多的,但是有4个主要缺点:
-
%右侧那个元组里面的值如果类型和顺序有变化,那么程序转换类型时可能不兼容出错。
例如,把上面那个例子的元组里的key和value调换位置或把字符串里的操作符调换位置,就会出现异常,可自行实验下。 -
如果填充的值比较多或需要对填充的值进行调整,那右边元组里的表达式就会非常长。
-
如果同一个值填充字符串多个位置,必须要在右侧元组多次重复该值。
为了解决上述问题,%操作操作符允许使用dict取代tuple。
如下:
key = "my_var"
value = 1.234
formatted = "We have key:%(key)s and value:%(value)f, then format to %(key)s = %(value)f" % {"key": key, "value": value}
print(formatted)
# We have key:my_var and value:1.234000, then format to my_var = 1.234000
- 上述使用dict的写法会让代码变多,在格式字符串里每个变了写了至少一次,在%后的字典里每个键至少写两次。
2. 使用format
format在格式化字符串时,会把格式有待调整的哪些位置用{}代替,然后从左到右的顺序,把需要填的值传给format方法,如下:
key = "my_var"
value = 1.234
formatted = "{} = {}".format(key, value)
print(formatted) # my_var = 1.234
当然也可以使用:
来添加格式说明符,格式说明符见扩展内容,下面是一个小例子:
formatted = "{:<10} = {:.2f}".format(key, value)
print(formatted)
# my_var = 1.23
另外,每个类可以通过__format__
这个特殊方法指定相应的逻辑,这样,format函数把示例转成字符串时,会按照这个逻辑来转。
使用format时,还可以在{}里使用数字,用来表示format方法在这个位置接受的参数位置索引。以后即使格式化字符串的次序有所变化,也不用调换format方法的参数。这样解决了第一种%方法的第一个缺点。例子如下:
formatted = "{1} = {0}".format(key, value)
print(formatted)
# 1.234 = my_var
且同一个位置索引可以在字符串的多个{}里出现,这样不用重复传值了。解决了是一种%方法的第三个缺点。例子如下:
name = "Tom"
formatted = "{0} loves food. See {0} cook.".format(name)
print(formatted)
# Tom loves food. See Tom cook.
然而format解决不了第一种方法的第二个缺点,即当需要格式化的比较多,且有格式转换,format里参数也有很多。
当然,{}形式的说明符,还支持一些高级的用法,比如可以使用dict的某个键的值,也可以访问list的元素,还可以把Unicode转为repr字符串。如下:
menu = {
"soup": "lentil",
"oyster": "kumamoto",
"special": "schnitzel"
}
formatted = "First Letter is {menu[oyster][0]!r}".format(menu=menu)
print(formatted)
# First Letter is 'k'
但是这些特性没能解决前面提到的第四个缺点,也就是键名多次重复的问题。
3.f-string方法
python 3.6天假一种新特性,叫作插值格式字符串,可以解决上述所有问题。
新语法要求在字符串前面加上f作为前缀。如下:
key = "my_var"
value = 1.234
formatted = f"{key} = {value}"
print(formatted)
# my_var = 1.234
str.format
方法{}内支持的那套语言格式,在f-string方法的{}内都可以使用。如下:
formatted = f"{key!r:<10} = {value:.2f}"
print(formatted)
# 'my_var' = 1.23
可以看出,f-string方法可以实现所有功能的同时,代码量是最小的。
另外,python的表达式也可以出现在格式说明符中,如下代码把小数点之后的位数用变量来表示了,并放在了{}里的说明符中,这样更加灵活:
places = 3
number = 1.23456
print(f"My number if {number:.{places}f}")
# My number if 1.235
f-string是个简洁强大的机制,并且灵活应用python表达式操作说明符,推荐使用!
扩展
格式说明符使用补充
1.格式符
格式符为真实值预留位置,并控制显示的类型。
%s 字符串 (采用str()的显示)
%r 字符串 (采用repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为e)
%E 指数 (基底写为E)
%f 浮点数
%F 浮点数,与上相同
%g 指数(e)或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)
%% 字符"%"
2.填充对齐
^, <, >
分别是居中、左对齐、右对齐,后面带宽度,:
号后面带填充的字符,只能是一个字符,不指定则默认是用空格填充。
3,精度
.2f
表示到小数点后两位。
参考
Effective Python 第二版
python3文档:string字符串操作