Effective Python 第4条:格式化字符串的三种方法比较

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个主要缺点:

  1. %右侧那个元组里面的值如果类型和顺序有变化,那么程序转换类型时可能不兼容出错。
    例如,把上面那个例子的元组里的key和value调换位置或把字符串里的操作符调换位置,就会出现异常,可自行实验下。

  2. 如果填充的值比较多或需要对填充的值进行调整,那右边元组里的表达式就会非常长。

  3. 如果同一个值填充字符串多个位置,必须要在右侧元组多次重复该值。
    为了解决上述问题,%操作操作符允许使用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
  1. 上述使用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字符串操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan-running

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值