你所不知道的Python | 字串格式化的演進之路

simpleapples發表於2018-06-11

字串格式化對於每個語言來說都是一個非常基礎和常用的功能,學習Python的同學大概都知道可以用%語法來格式化字串。然而為了讓我們更方便的使用這個常用功能,語言本身也在對字串格式化方法進行迭代。

Python 2.6以前:%操作符

在Python 2.6出現之前,字串迭代只有一種方法,就是%(也是取模)操作符,%操作符支援unicode和str型別的Python字串,效果和C語言中的sprintf()方法相似,下面是一個使用%格式化字串的例子:

print("I'm %s. I'm %d year old" % ('Tom', 27))
複製程式碼

%符號前面使用一個字串作為模板,模板中有標記格式的佔位符號,%後面是一個tuple或者dict,用來傳遞需要格式化的值。佔位符控制著顯示的格式,下面列表展示了佔位符的種類:

佔位符 內容
%d 十進位制整數
%i 十進位制整數
%o 八進位制整數
%u 無符號整數
%x 無符號十六進位制(小寫)
%X 無符號十六進位制(大寫)
%e 浮點型(科學記數法,小寫)
%E 浮點型(科學記數法,大寫)
%f 浮點數
%F 浮點數
%g 浮點型,如果小數位數超過4位,使用科學記數法表示(小寫)
%G 浮點型,如果小數位數超過4位,使用科學記數法表示(大寫)
%c 單個字元
%r 字串(呼叫repr()方法生成)
%s 字串(呼叫str()方法生成)

除了對資料型別的指定,%操作符還支援更復雜的格式控制:

%[資料名稱][對齊標誌][寬度].[精度]型別
複製程式碼
名稱 內容
資料名稱 資料名稱用於字典賦值,如果%符號後面傳遞的陣列就不需要填寫了
對齊標誌 有+、-、0、‘ ’四種,+表示顯示正負數符號,-表示左對齊,空格表示在左側填充一個空格,0表示用0填充
寬度 表示格式化後的字串長度,位數不足用0或空格補齊
精度 小數點後的位數
型別 資料型別(參考佔位符種類)

例如print('%053f' % '12.34')會輸出0012.340

Python 2.6:format函式

到Python2.6時,出現了一種新的字串格式化方式,str.format()函式,相比於%操作符,format函式使用{}和:代替了%,威力更加強大,在對映關係方面,format函式支援位置對映、關鍵字對映、物件屬性對映、下標對映等多種方式,不僅引數可以不按順序,也可以不用引數或者一個引數使用多次,下面通過幾個例子來說明。

'{1} {0}'.format('abc', 123# 可以不按順序進行位置對映,輸出'123 abc'

'{} {}'.format('abc', 123# 可以不指定引數名稱,輸出'abc 123'

'{1} {0} {1}'.format('abc', 123# 引數可以使用多次,輸出'123 abc 123'

'{name} {age}'.format(name='tom', age=27# 可以按關鍵字對映,輸出'tom 27'

'{person.name} {person.age}'.format(person=person)  # 可以按物件屬性對映,輸出'tom 27'

'{0[1]} {0[0]}'.format(lst)  # 通過下標對映
複製程式碼

可以看到,format函式比%操作符使用起來更加方便,不需要記住太多各種佔位符代表的意義,程式碼可讀性也更高。在複雜格式控制方面,format函式也提供了更加強大的控制方式:

[[填充字元]對齊方式][符號標誌][#][寬度][,][.精度][型別]
複製程式碼

例如:

'{:S^+#016,.2f}'.format(1234)  # 輸出'SSS+1,234.00SSSS'
複製程式碼

我們以上面的程式碼為例,通過表格說明一下format格式控制引數:

型別 說明 示例說明
填充字元 不填時預設用空格填充 S表示用S填充
對齊方式 ^表示居中對齊、<表示左對齊、>表示右對齊 ^表示居中對齊,左右位數不足部分會用填充字元填充
符號標誌 +表示有符號(正數前顯示+,負數前顯示-),空格表示整數前加一個空格以和負數對齊 +表示正數前顯示空格
# 表示是否在二進位制、八進位制、十六進位制前顯示0b、0o、0x等符號 #表示顯示進位制符號,由於是十進位制,所以不顯示
寬度 表示輸出字串的寬度 16表示字串寬度為16,不足部分會補齊
, 表示使用,作為千位分隔符 ,表示使用千位分隔符
精度 表示小數點後數字位數 .2表示精度為2為
型別 s表示字串型別,c表示字元型別,b\o\d分別表示二八十進位制,x\X表示小寫和大寫十六進位制,e\E表示小寫和大寫的科學記數法,f表示浮點型 f表示浮點型數字

可以看到format函式在%基礎上豐富了格式控制種類,並且使輸出更容易。

Python 3.6:f-string

不少使用過ES6的小夥伴會知道其中的模板字串,採用直接在字串中內嵌變數的方式進行字串格式化操作,Python在3.6版本中也為我們帶來了類似的功能:Formatted String Literals(字面量格式化字串),簡稱f-string。

f-string就是以f''開頭的字串,類似u''和b'',字串內容和format方法中的格式一樣,但是可以直接將變數帶入到字串中,可讀性進一步增加,例如:

amount = 1234
f'請轉賬給我{amount:,.2f}元'  # '請轉賬給我1,234.00元'
複製程式碼

同時,f-string的效能是比%和format都有提升的,我們做一個簡單的測試,分別使用%操作符、format和f-string將下面語句執行10000次:

'My name is %s and i'm %s years old.' % (name, age)
'My name is {} and i'm {} years old.'.format(name, age)
f'My name is {name} and i'm {age} years old.'
複製程式碼

用時結果如下:

你所不知道的Python | 字串格式化的演進之路

總結

如果你的專案使用的Python版本已經提升到3.6,f-string格式化是首選方式,不僅在保持功能強大的同時語義上更容易理解,而且效能也有較大的提升。如果專案還沒有提升到3.6或者使用的2.7,更建議使用format,雖然效能上沒有優勢,但是語義上還是比%操作符更加便於理解的,功能也更加強大。

歡迎關注我的公眾號【Python私房菜】

你所不知道的Python | 字串格式化的演進之路

相關文章