浅谈Python中的格式化字符%s format f

背景

Python环境中,有3种方法格式化字符串,分别是%s,formatf,这些格式化字符串方法各有其优劣势,现对比下,方便日后参考


环境

  • Python 3.8


对比

以入门案例再次为例吧,我们需要根据用户名,加上hello,组成一个招呼. 假设我的用户名是Dan,预期输出

hello Dan

1. 基础使用方法

%s方式会这样写

'hello %s' % 'Dan'

format方式会这样写

'hello {}'.format('Dan')

f方式必须得用到变量,所以留到下一轮对比

在不使用变量的情况下,这一轮的比较结果:

  • %s代码简洁,纯字符串都不像使用了代码
  • format代码简洁,加入了函数名显得专业
  • f无法使用

2. 部分使用变量

仅将传入的姓名使用变量, 格式化字符不使用,会是下面这样

name = 'Dan'    # 变量赋值

%s方式

'hello %s' % name

format方式有3种

'hello {}'.format(name)
'hello {0}'.format(name)
'hellow {name}'.format(name=name)

f方式

f'hello {name}'

使用部分变量的情况下,这一轮的比较结果

  • %s代码依然简洁
  • format虽专业但略显拖沓,但是方式多样,优势不输
  • f代码超级简洁易懂!

私以为在这种情况下,f最能体现Python精神

3. 全部使用变量

将模板,传入姓名全部使用变量,会是下面这样

  • %s方式
tmpt = 'hello %s'
name = 'Dan'
tmpt % name
  • format方式仍然是3种
tmpt = 'hello {}'
name = 'Dan'
tmpt.format(name)
tmpt = 'hello {0}'
name = 'Dan'
tmpt.format(name)
tmpt = 'hello {name}'
name = 'Dan'
tmpt.format(name=name)
  • f方式
tmpt = 'hello'
name = 'Dan'
f'{tempt} {name}'

使用全部变量的情况下,这一轮的比较结果

  • %sf略显累赘
  • format的多样和专业在此更显优势

4. 数字格式

在使用字符串格式的过程中,我们最长使用的是数字格式,尤其是对于浮点数的转换,一般是变成整数,或者保留例如2位的小数点
假设这里有一个数字如下,我们需要实现千分位+保留2位小数

num = 12345.6789

预期结果如下

本月营业额为: 12,345.68元

%s找不到实现方式,主要是没有千分位,小数点后2位写做%.2f
format仍然是上述3种实现方式

'本月营业额为: {:,.2f}元'.format(num)          # 无参数名
'本月营业额为: {0:,.2f}元'.format(num)     # 位置参数,从0开始
'本月营业额为: {num:,.2f}元'.format(num=num)   # 指定参数名

f方式

f'本月营业额为: {num:,.2f}元'

相对复杂的数字格式这一轮,结果如下

  • format与仍然多样而专业
  • f在此更简洁,格式化方面与format一致
  • %s由于功能简单而无法直接实现

5. 实际使用

在实际使用过程中,每个人有不同的习惯,个人使用习惯是上面第2项,也就是

模板字符串固定,使用的时候直接写出
可能变化字符串使用变量赋值,方便更改变量

通常格式化的使用场景有

  • 日志输出
  • 话术播报
  • 邮件正文
  • SQL组装
  • 等等等等...

以SQL组装为例

一般情况下,需要传入的参数比较少,我会直接写%s,因为简单无脑,还是第一反应

date= '2022-03-15'
sql = "select * from sd.log_web where create_time >= '%s 00:00:00'" % val

也会写format,不带参数的那种

date= '2022-03-15'
sql = "select * from sd.log_web where create_time >= '{} 00:00:00'".format(val)

位置参数例如{0}这种,和%s是实际上一样的作用.正常能写%s就不会写{0}


insert数据经常比较变态的是,拼装SQL由于字段超长,需要些很多很多变量,上面那种位置传参极容易导致人工写错位置传入不对的bug. 例如这个表有10个字段,如果按照位置参数写会变成这样

sql = "insert into sd.log_web values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)".format(a,b,c,d,e,f,g,h,i,j)

眼花缭乱啊用format就好看好多

sql = "insert into sd.log_web values ({a},{b},{c},{d},{e},{f},{g},{h},{i},{j})".format(a=a,b=b,c=c,d=d,e=e,f=f,g=g,h=h,j=j,i=i)

这种不需要位置对,只需要传入的参数对,谁前谁后完全不打紧
但是我还是更喜欢f这么简洁,不用考虑位置,也不用写3遍变量

sql = f"insert into sd.log_web values ({a},{b},{c},{d},{e},{f},{g},{h},{i},{j})"

有的时候,同一个参数会出现在SQL脚本多处,这个时候用format会省心太多

date = '2022-03-15'
sql  = "select everyday,flow from sd.log_web where everyday >= '{date} 00:00:00' and everyday <= '{date} 23:59:59'".format(date=date)

复杂字符串的处理,甚至f都不能代替.因为format还有外在变量
假设上面的字符串,我们需要把变量从date替换为day,替换之前,formatf写法差不多,替换后,f就要麻烦很多
format只需要改动一下传入的参数名

day = '2022-03-15'
sql = "select everyday,flow from sd.log_web where everyday >= '{date} 00:00:00' and everyday <= '{date} 23:59:59'".format(date=day)

f却需要改动全部变量

day = '2022-03-15'
sql = "select everyday,flow from sd.log_web where everyday >= '{day} 00:00:00' and everyday <= '{day} 23:59:59'"


总结

每种场景都有不同的需求,在此总结一下三种格式化字符串的对比结果

适用场景 %s format f
重复出现同样的变量  
需要按位置传参
代码尽可能简洁易懂
数字格式化
无脑快速传参
变量很多
编写SQL
提前预备模板字符串  
变量名变化频繁  
代码阅读友好

format在其多样的写法基础上,几乎全能了
但我还是更偏爱f

你可能感兴趣的:(浅谈Python中的格式化字符%s format f)