Python格式化字串f-string f「{}{}{}「詳細介紹

2020-08-12 19:15:32

簡介

f-string,亦稱爲格式化字串常數(formatted string literals),是Python3.6新引入的一種字串格式化方法,該方法源於PEP 498 – Literal String Interpolation,主要目的是使格式化字串的操作更加簡便。f-string在形式上是以 f 或 F 修飾符引領的字串(f'xxx'或 F'xxx'),以大括號 {} 標明被替換的欄位;f-string在本質上並不是字串常數,而是一個在執行時運算求值的表達式:

While other string literals always have a constant value, formatted strings are really expressions evaluated at run time. 
(與具有恆定值的其它字串常數不同,格式化字串實際上是執行時運算求值的表達式。) 
—— Python Documentation

f-string在功能方面不遜於傳統的%-formatting語句str.format()函數,同時效能又優於二者,且使用起來也更加簡潔明瞭,因此對於Python3.6及以後的版本,推薦使用f-string進行字串格式化。

用法

此部分內容主要參考以下資料:

簡單使用

f-string用大括號 {} 表示被替換欄位,其中直接填入替換內容:

  1. >>> name = 'Eric'
  2. >>> f'Hello, my name is {name}'
  3. 'Hello, my name is Eric'
  4. >>> number = 7
  5. >>> f'My lucky number is {number}'
  6. 'My lucky number is 7'
  7. >>> price = 19.99
  8. >>> f'The price of this book is {price}'
  9. 'The price of this book is 19.99'
  • 表達式求值與函數呼叫

f-string的大括號 {} 可以填入表達式或呼叫函數,Python會求出其結果並填入返回的字串內:

  1. >>> f'A total number of {24 * 8 + 4}'
  2. 'A total number of 196'
  3. >>> f'Complex number {(2 + 2j) / (2 - 3j)}'
  4. 'Complex number (-0.15384615384615388+0.7692307692307692j)'
  5. >>> name = 'ERIC'
  6. >>> f'My name is {name.lower()}'
  7. 'My name is eric'
  8. >>> import math
  9. >>> f'The answer is {math.log(math.pi)}'
  10. 'The answer is 1.1447298858494002'
  • 引號、大括號與反斜槓

f-string大括號內所用的引號不能和大括號外的引號定界符衝突,可根據情況靈活切換 ' 和 "

  1. >>> f'I am {"Eric"}'
  2. 'I am Eric'
  3. >>> f'I am {'Eric'}'
  4. File "<stdin>", line 1
  5. f'I am {'Eric'}'
  6. ^
  7. SyntaxError: invalid syntax
  • 若 ' 和 " 不足以滿足要求,還可以使用 ''' 和 """
  1. >>> f"He said {"I'm Eric"}"
  2. File "<stdin>", line 1
  3. f"He said {"I'm Eric"}"
  4. ^
  5. SyntaxError: invalid syntax
  6. >>> f'He said {"I'm Eric"}'
  7. File "<stdin>", line 1
  8. f'He said {"I'm Eric"}'
  9. ^
  10. SyntaxError: invalid syntax
  11. >>> f"""He said {"I'm Eric"}"""
  12. "He said I'm Eric"
  13. >>> f'''He said {"I'm Eric"}'''
  14. "He said I'm Eric"
  • 大括號外的引號還可以使用 \ 跳脫,但大括號內不能使用 \ 跳脫:
  1. >>> f'''He\'ll say {"I'm Eric"}'''
  2. "He'll say I'm Eric"
  3. >>> f'''He'll say {"I\'m Eric"}'''
  4. File "<stdin>", line 1
  5. SyntaxError: f-string expression part cannot include a backslash
  • f-string大括號外如果需要顯示大括號,則應輸入連續兩個大括號 {{ 和 }}
  1. >>> f'5 {"{stars}"}'
  2. '5 {stars}'
  3. >>> f'{{5}} {"stars"}'
  4. '{5} stars'
  • 上面提到,f-string大括號內不能使用 \ 跳脫,事實上不僅如此,f-string大括號內根本就不允許出現 \。如果確實需要 \,則應首先將包含 \ 的內容用一個變數表示,再在f-string大括號內填入變數名:
  1. >>> f"newline: {ord('\n')}"
  2. File "<stdin>", line 1
  3. SyntaxError: f-string expression part cannot include a backslash
  4. >>> newline = ord('\n')
  5. >>> f'newline: {newline}'
  6. 'newline: 10'
  • 多行f-string

f-string還可用於多行字串:

  1. >>> name = 'Eric'
  2. >>> age = 27
  3. >>> f"Hello!" \
  4. ... f"I'm {name}." \
  5. ... f"I'm {age}."
  6. "Hello!I'm Eric.I'm 27."
  7. >>> f"""Hello!
  8. ... I'm {name}.
  9. ... I'm {age}."""
  10. "Hello!\n I'm Eric.\n I'm 27."
  • 自定義格式:對齊、寬度、符號、補零、精度、進位制等

f-string採用 {content:format} 設定字串格式,其中 content 是替換並填入字串的內容,可以是變數、表達式或函數等,format是格式描述符。採用預設格式時不必指定 {:format},如上面例子所示只寫 {content} 即可。

關於格式描述符的詳細語法及含義可查閱Python官方文件,這裏按使用時的先後順序簡要介紹常用格式描述符的含義與作用:

對齊相關格式描述符

格式描述符 含義與作用
< 左對齊(字串預設對齊方式)
> 右對齊(數值預設對齊方式)
^ 居中

數位符號相關格式描述符

格式描述符 含義與作用
+ 負數前加負號(-),正數前加正號(+
- 負數前加負號(-),正數前不加任何符號(預設)
(空格) 負數前加負號(-),正數前加一個空格

注:僅適用於數值型別。

數位顯示方式相關格式描述符

格式描述符 含義與作用
# 切換數位顯示方式

注1:僅適用於數值型別。 
注2:# 對不同數值型別的作用效果不同,詳見下表:

數值型別 不加#(預設) # 區別
二進制整數 '1111011' '0b1111011' 開頭是否顯示 0b
八進制整數 '173' '0o173' 開頭是否顯示 0o
十進制整數 '123' '123' 無區別
十六進制整數(小寫字母) '7b' '0x7b' 開頭是否顯示 0x
十六進制整數(大寫字母) '7B' '0X7B' 開頭是否顯示 0X

寬度與精度相關格式描述符

格式描述符 含義與作用
width 整數 width 指定寬度
0width 整數 width 指定寬度,開頭的 0 指定高位用 0 補足寬度
width.precision 整數 width 指定寬度,整數 precision 指定顯示精度

注1:0width 不可用於複數型別和非數值型別,width.precision 不可用於整數型別。 
注2:width.precision 用於不同格式型別的浮點數、複數時的含義也不同:用於 fFeE 和 % 時 precision 指定的是小數點後的位數,用於 g 和 G 時 precision 指定的是有效數位位數(小數點前位數+小數點後位數)。 
注3:width.precision 除浮點數、複數外還可用於字串,此時 precision 含義是隻使用字串中前 precision 位字元。

範例:

  1. >>> a = 123.456
  2. >>> f'a is {a:8.2f}'
  3. 'a is 123.46'
  4. >>> f'a is {a:08.2f}'
  5. 'a is 00123.46'
  6. >>> f'a is {a:8.2e}'
  7. 'a is 1.23e+02'
  8. >>> f'a is {a:8.2%}'
  9. 'a is 12345.60%'
  10. >>> f'a is {a:8.2g}'
  11. 'a is 1.2e+02'
  12. >>> s = 'hello'
  13. >>> f's is {s:8s}'
  14. 's is hello '
  15. >>> f's is {s:8.3s}'
  16. 's is hel '
  • 千位分隔符相關格式描述符
格式描述符 含義與作用
, 使用,作爲千位分隔符
_ 使用_作爲千位分隔符

注1:若不指定 , 或 _,則f-string不使用任何千位分隔符,此爲預設設定。 
注2:, 僅適用於浮點數、複數與十進制整數:對於浮點數和複數,, 只分隔小數點前的數位。 
注3:_ 適用於浮點數、複數與二、八、十、十六進制整數:對於浮點數和複數,_ 只分隔小數點前的數位;對於二、八、十六進制整數,固定從低位到高位每隔四位插入一個 _(十進制整數是每隔三位插入一個 _)。

範例:

  1. >>> a = 1234567890.098765
  2. >>> f'a is {a:f}'
  3. 'a is 1234567890.098765'
  4. >>> f'a is {a:,f}'
  5. 'a is 1,234,567,890.098765'
  6. >>> f'a is {a:_f}'
  7. 'a is 1_234_567_890.098765'
  8. >>> b = 1234567890
  9. >>> f'b is {b:_b}'
  10. 'b is 100_1001_1001_0110_0000_0010_1101_0010'
  11. >>> f'b is {b:_o}'
  12. 'b is 111_4540_1322'
  13. >>> f'b is {b:_d}'
  14. 'b is 1_234_567_890'
  15. >>> f'b is {b:_x}'
  16. 'b is 4996_02d2'
  • 格式型別相關格式描述符

基本格式型別

格式描述符 含義與作用 適用變數型別
s 普通字串格式 字串
b 二進制整數格式 整數
c 字元格式,按unicode編碼將整數轉換爲對應字元 整數
d 十進制整數格式 整數
o 八進制整數格式 整數
x 十六進制整數格式(小寫字母) 整數
X 十六進制整數格式(大寫字母) 整數
e 科學計數格式,以 e 表示 ×10^ 浮點數、複數、整數(自動轉換爲浮點數)
E 與 e 等價,但以 E 表示 ×10^ 浮點數、複數、整數(自動轉換爲浮點數)
f 定點數格式,預設精度(precision)是6 浮點數、複數、整數(自動轉換爲浮點數)
F 與 f 等價,但將 nan 和 inf 換成 NAN 和 INF 浮點數、複數、整數(自動轉換爲浮點數)
g 通用格式,小數用 f,大數用 e 浮點數、複數、整數(自動轉換爲浮點數)
G 與 G 等價,但小數用 F,大數用 E 浮點數、複數、整數(自動轉換爲浮點數)
% 百分比格式,數位自動乘上100後按 f 格式排版,並加 % 後綴 浮點數、整數(自動轉換爲浮點數)

常用的特殊格式型別:標準庫 datetime 給定的用於排版時間資訊的格式型別,適用於 datedatetime 和 time 物件

格式描述符 含義 顯示樣例
%a 星期幾(縮寫) 'Sun'
%A 星期幾(全名) 'Sunday'
%w 星期幾(數位,0 是週日,6 是週六) '0'
%u 星期幾(數位,1 是週一,7 是週日) '7'
%d 日(數位,以 0 補足兩位) '07'
%b 月(縮寫) 'Aug'
%B 月(全名) 'August'
%m 月(數位,以 0 補足兩位) '08'
%y 年(後兩位數位,以 0 補足兩位) '14'
%Y 年(完整數位,不補零) '2014'
%H 小時(24小時制,以 0 補足兩位) '23'
%I 小時(12小時制,以 0 補足兩位) '11'
%p 上午/下午 'PM'
%M 分鐘(以 0 補足兩位) '23'
%S 秒鐘(以 0 補足兩位) '56'
%f 微秒(以 0 補足六位) '553777'
%z UTC偏移量(格式是 ±HHMM[SS],未指定時區則返回空字串) '+1030'
%Z 時區名(未指定時區則返回空字串) 'EST'
%j 一年中的第幾天(以 0 補足三位) '195'
%U 一年中的第幾周(以全年首個週日後的星期爲第0周,以 0 補足兩位) '27'
%w 一年中的第幾周(以全年首個週一後的星期爲第0周,以 0 補足兩位) '28'
%V 一年中的第幾周(以全年首個包含1月4日的星期爲第1周,以 0 補足兩位) '28'

綜合範例

  1. >>> a = 1234
  2. >>> f'a is {a:^#10X}' # 居中,寬度10位,十六進制整數(大寫字母),顯示0X字首
  3. 'a is 0X4D2 '
  4. >>> b = 1234.5678
  5. >>> f'b is {b:<+10.2f}' # 左對齊,寬度10位,顯示正號(+),定點數格式,2位小數
  6. 'b is +1234.57 '
  7. >>> c = 12345678
  8. >>> f'c is {c:015,d}' # 高位補零,寬度15位,十進制整數,使用,作爲千分分割位
  9. 'c is 000,012,345,678'
  10. >>> d = 0.5 + 2.5j
  11. >>> f'd is {d:30.3e}' # 寬度30位,科學計數法,3位小數
  12. 'd is 5.000e-01+2.500e+00j'
  13. >>> import datetime
  14. >>> e = datetime.datetime.today()
  15. >>> f'the time is {e:%Y-%m-%d (%a) %H:%M:%S}' # datetime時間格式
  16. 'the time is 2018-07-14 (Sat) 20:46:02'
  • lambda表達式

f-string大括號內也可填入lambda表達式,但lambda表達式的 : 會被f-string誤認爲是表達式與格式描述符之間的分隔符,爲避免歧義,需要將lambda表達式置於括號 () 內:

  1. >>> f'result is {lambda x: x ** 2 + 1 (2)}'
  2. File "<fstring>", line 1
  3. (lambda x)
  4. ^
  5. SyntaxError: unexpected EOF while parsing
  6. >>> f'result is {(lambda x: x ** 2 + 1) (2)}'
  7. 'result is 5'
  8. >>> f'result is {(lambda x: x ** 2 + 1) (2):<+7.2f}'
  9. 'result is +5.00 '