背景
在Python
環(huán)境中,有3種方法格式化字符串,分別是%s
,format
和f
,這些格式化字符串方法各有其優(yōu)劣勢(shì),現(xiàn)對(duì)比下,方便日后參考
環(huán)境
-
Python
3.8
對(duì)比
以入門(mén)案例再次為例吧,我們需要根據(jù)用戶名,加上hello,組成一個(gè)招呼. 假設(shè)我的用戶名是Dan,預(yù)期輸出
hello Dan
1. 基礎(chǔ)使用方法
%s
方式會(huì)這樣寫(xiě)
'hello %s' % 'Dan'
format
方式會(huì)這樣寫(xiě)
'hello {}'.format('Dan')
f
方式必須得用到變量,所以留到下一輪對(duì)比
在不使用變量的情況下,這一輪的比較結(jié)果:
-
%s
代碼簡(jiǎn)潔,純字符串都不像使用了代碼 -
format
代碼簡(jiǎn)潔,加入了函數(shù)名顯得專業(yè) -
f
無(wú)法使用
2. 部分使用變量
僅將傳入的姓名使用變量, 格式化字符不使用,會(huì)是下面這樣
name = 'Dan' # 變量賦值
%s
方式
'hello %s' % name
format
方式有3種
'hello {}'.format(name)
'hello {0}'.format(name)
'hellow {name}'.format(name=name)
f
方式
f'hello {name}'
使用部分變量的情況下,這一輪的比較結(jié)果
-
%s
代碼依然簡(jiǎn)潔 -
format
雖專業(yè)但略顯拖沓,但是方式多樣,優(yōu)勢(shì)不輸 -
f
代碼超級(jí)簡(jiǎn)潔易懂!
私以為在這種情況下,f
最能體現(xiàn)Python
精神
3. 全部使用變量
將模板,傳入姓名全部使用變量,會(huì)是下面這樣
-
%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}'
使用全部變量的情況下,這一輪的比較結(jié)果
-
%s
和f
略顯累贅 -
format
的多樣和專業(yè)在此更顯優(yōu)勢(shì)
4. 數(shù)字格式
在使用字符串格式的過(guò)程中,我們最長(zhǎng)使用的是數(shù)字格式,尤其是對(duì)于浮點(diǎn)數(shù)的轉(zhuǎn)換,一般是變成整數(shù),或者保留例如2位的小數(shù)點(diǎn)
假設(shè)這里有一個(gè)數(shù)字如下,我們需要實(shí)現(xiàn)千分位+保留2位小數(shù)
num = 12345.6789
預(yù)期結(jié)果如下
本月?tīng)I(yíng)業(yè)額為: 12,345.68元
%s
找不到實(shí)現(xiàn)方式??,主要是沒(méi)有千分位,小數(shù)點(diǎn)后2位寫(xiě)做%.2f
format
仍然是上述3種實(shí)現(xiàn)方式
'本月?tīng)I(yíng)業(yè)額為: {:,.2f}元'.format(num) # 無(wú)參數(shù)名
'本月?tīng)I(yíng)業(yè)額為: {0:,.2f}元'.format(num) # 位置參數(shù),從0開(kāi)始
'本月?tīng)I(yíng)業(yè)額為: {num:,.2f}元'.format(num=num) # 指定參數(shù)名
f
方式
f'本月?tīng)I(yíng)業(yè)額為: {num:,.2f}元'
相對(duì)復(fù)雜的數(shù)字格式這一輪,結(jié)果如下
-
format
與仍然多樣而專業(yè) -
f
在此更簡(jiǎn)潔,格式化方面與format
一致 -
%s
由于功能簡(jiǎn)單而無(wú)法直接實(shí)現(xiàn)
5. 實(shí)際使用
在實(shí)際使用過(guò)程中,每個(gè)人有不同的習(xí)慣,個(gè)人使用習(xí)慣是上面第2項(xiàng),也就是
模板字符串固定,使用的時(shí)候直接寫(xiě)出
可能變化字符串使用變量賦值,方便更改變量
通常格式化的使用場(chǎng)景有
- 日志輸出
- 話術(shù)播報(bào)
- 郵件正文
- SQL組裝
- 等等等等...
以SQL組裝為例
一般情況下,需要傳入的參數(shù)比較少,我會(huì)直接寫(xiě)%s
,因?yàn)楹?jiǎn)單無(wú)腦,還是第一反應(yīng)
date= '2022-03-15'
sql = "select * from sd.log_web where create_time >= '%s 00:00:00'" % val
也會(huì)寫(xiě)format
,不帶參數(shù)的那種
date= '2022-03-15'
sql = "select * from sd.log_web where create_time >= '{} 00:00:00'".format(val)
位置參數(shù)例如{0}
這種,和%s
是實(shí)際上一樣的作用.正常能寫(xiě)%s
就不會(huì)寫(xiě){0}
insert
數(shù)據(jù)經(jīng)常比較變態(tài)的是,拼裝SQL由于字段超長(zhǎng),需要些很多很多變量,上面那種位置傳參極容易導(dǎo)致人工寫(xiě)錯(cuò)位置傳入不對(duì)的bug. 例如這個(gè)表有10個(gè)字段,如果按照位置參數(shù)寫(xiě)會(huì)變成這樣
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},,{c},xjpk7r5,{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)
這種不需要位置對(duì),只需要傳入的參數(shù)對(duì),誰(shuí)前誰(shuí)后完全不打緊
但是我還是更喜歡f
這么簡(jiǎn)潔??,不用考慮位置,也不用寫(xiě)3遍變量
sql = f"insert into sd.log_web values ({a},捧灰,{c},prcn3mq,{e},{f},{g},{h},{i},{j})"
有的時(shí)候,同一個(gè)參數(shù)會(huì)出現(xiàn)在SQL腳本多處,這個(gè)時(shí)候用format
會(huì)省心太多
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ù)雜字符串的處理,甚至f
都不能代替.因?yàn)?code>format還有外在變量
假設(shè)上面的字符串,我們需要把變量從date
替換為day
,替換之前,format
和f
寫(xiě)法差不多,替換后,f
就要麻煩很多
format
只需要改動(dòng)一下傳入的參數(shù)名
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
卻需要改動(dòng)全部變量
day = '2022-03-15'
sql = "select everyday,flow from sd.log_web where everyday >= '{day} 00:00:00' and everyday <= '{day} 23:59:59'"
總結(jié)
每種場(chǎng)景都有不同的需求,在此總結(jié)一下三種格式化字符串的對(duì)比結(jié)果
適用場(chǎng)景 | %s |
format |
f |
---|---|---|---|
重復(fù)出現(xiàn)同樣的變量 | √ | ? | |
需要按位置傳參 | √ | √ | |
代碼盡可能簡(jiǎn)潔易懂 | √ | √ | |
數(shù)字格式化 | √ | √ | |
無(wú)腦快速傳參 | √ | √ | √ |
變量很多 | √ | √ | |
編寫(xiě)SQL | √ | √ | √ |
提前預(yù)備模板字符串 | √ | √ | ? |
變量名變化頻繁 | √ | ? | |
代碼閱讀友好 | √ |
format
在其多樣的寫(xiě)法基礎(chǔ)上,幾乎全能了
但我還是更偏愛(ài)f