如何格式化 Python 字串?format,format_map 方法,Formatter 類別介紹
本節內容不涉及 Python 舊式 printf 風格的字串格式化,你可以檢視Python 舊式 printf 風格字串格式化使用說明一節來了解相關資訊。
Python 字串格式化中的取代欄位
對於需要進行格式化的 Python 字串,他們通常含有一些取代(格式)欄位,取代欄位由一個{}
及其包含的內容組成,並會被運算結果取代。
取代欄位可能被 Pythonstr
型別的format
和format_map
方法,格式化字串,或string
模組的Formatter
類別使用,以用來參考方法的參數或目前可存取的變數等內容。
如何在格式化 Python 字串時表示大括弧自身?
在對 Python 字串進行格式化時,{}
會被解釋為取代欄位,如果要在字串中表示{
或}
自身,那麽需要將其書寫為{{
或}}
。
'{{}}'.format()
'{}'
Python str 型別的 format,format_map 方法
Pythonstr
型別的format
和format_map
方法,提供了格式化 Python 字串的功能,只需要在字串中書寫取代欄位,即可參考format
和format_map
方法提供的參數。
format(*args, **kwargs)
format_map(mapping)
- args 參數
可變參數
args
所包含的位置參數將被 Python 字串中的取代欄位參考。- kwargs 參數
可變參數
kwargs
所包含的關鍵字參數將被 Python 字串中的取代欄位參考。- mapping 參數
參數
mapping
通常是一個 Python 字典物件或通過__getitem__
方法提供值的物件,這些物件提供的值將被 Python 字串中的取代欄位參考。
在下面的範例中,我們定義了一個用於格式化的 Python 類別Data
,該類別將提供姓名和年齡資訊,你需要在字串中使用{name}
和{age}
來參考他們。
# 一個用於格式化的類別
class Data:
def __getitem__(self, key):
# 提供姓名和年齡資訊
if key == 'name':
return 'Jack'
elif key == 'age':
return 12
# 使用 {name} 和 {age} 進行參考
print('{name} 的年齡是 {age}'.format_map(Data()))
Jack 的年齡是 12
Python 格式化字串
Python 格式化字串是以f
或F
為首碼的字串,此類字串可以包含取代欄位,並在其中書寫 Python 運算式,運算式的計算結果將代替取代欄位出現在字串中。
a = 1
b = 2
F'{a} + {b} = {a + b}'
'1 + 2 = 3'
c = {'name': 'Jack', 'age': 12}
f'{len(c["name"]) > 3} {c["age"] > 12}'
'True False'
Python string 模組的 Formatter 類別
Pythonstring
模組的Formatter
類別,同樣可用於格式化 Python 字串,該類別的執行個體方法format
和vformat
可實作與str
型別的format
和format_map
方法類似的效果。
formatter.format(format_string, /, *args, **kwargs)
- format_string 參數
參數
format_string
是需要進行格式化的 Python 字串。- args 參數
可變參數
args
所包含的位置參數將被format_string
參數中的取代欄位參考。- kwargs 參數
可變參數
kwargs
所包含的關鍵字參數將被format_string
參數中的取代欄位參考。
formatter.vformat(format_string, args, kwargs)
- format_string 參數
參數
format_string
是需要進行格式化的 Python 字串。- args 參數
參數
args
是一個 Python 序列物件,其包含的元素(項)將被 Python 字串中的取代欄位參考。- kwargs 參數
參數
kwargs
是一個 Python 對映物件,其包含的元素(項)將被 Python 字串中的取代欄位參考。
import string
f = string.Formatter()
f.format('{name} {0}', 12, name='Jack')
'Jack 12'
f.vformat('{name} {0}', (12,), {'name': 'Jack'})
'Jack 12'
在字串中參考方法的參數
對於 Pythonstr
型別的format
和format_map
方法,以及string
模組的Formatter
物件的format
和vformat
方法,字串中的取代欄位{}
將按照出現順序參考format
方法中的位置參數,第一個出現的{}
參考第一個位置參數,第二個出現的{}
參考第二個位置參數,以此類推。
'{}: "{}"'.format('Jack', 'HELLO')
'Jack: "HELLO"'
如果需要在 Pythonstr
型別的format
方法,以及string
模組的Formatter
物件的format
和vformat
方法中參考指定位置的位置參數,那麽可以在{}
中填寫位置參數的索引,0
表示參考第一個位置參數。
Python 字串中的取代欄位不能參考不存在於 format 方法的位置參數
對於 Python 字串中的取代欄位{}
,如果其包含的索引所對應的位置參數不存在,那麽例外狀況IndexError: Replacement index … out of range for positional args tuple
將被引發。
'{0}: "{1}"'.format('Jack', 'HELLO')
'Jack: "HELLO"'
'{1}: "{0}"'.format('Jack', 'HELLO')
'HELLO: "Jack"'
'{0}: "{1}, {2}"'.format('Jack', 'HELLO')
…
IndexError: Replacement index 2 out of range for positional args tuple
如果需要在 Pythonstr
型別的format
或format_map
方法,以及string
模組的Formatter
物件的format
和vformat
方法中參考關鍵字參數,那麽可以在{}
中填寫關鍵字參數的名稱。
Python 字串中的取代欄位不能參考不存在於 format,format_map 方法的關鍵字參數
如果 Python 字串中的取代欄位{}
所參考的關鍵字參數,並不存在於format
或format_map
方法,那麽例外狀況KeyError: '…'
將被引發。
'{name}: "{word}"'.format(name='Jack', word='HELLO')
'Jack: "HELLO"'
'{name}: "{word}"'.format_map({'name': 'Jack', 'word': 'HELLO'})
'Jack: "HELLO"'
'{name}: "{word} {other}"'.format_map({'name': 'Jack', 'word': 'HELLO'})
…
KeyError: 'other'
在字串中參考方法的參數的特性
對於 Pythonstr
型別的format
和format_map
方法,以及string
模組的Formatter
物件的format
和vformat
方法,在字串的取代欄位中書寫.attribute
可以存取相關參數的特性(比如,變數,屬性等),其中attribute
為特性的名稱。而書寫[key]
可以間接呼叫相關參數的__getitem__
方法,這意味著你可以在取代欄位中存取 Python 串列或字典的值。需要指出,在[key]
中書寫引號是不可行的,比如[age]
不能書寫為["age"]
或['age']
。
'{0.real} {0.imag}'.format(12.3-4.56j)
'12.3 -4.56'
'{0[0]} {0[1]} {1[name]} {1[age]}'.format((1, 2), {'name': 'jack', 'age': 12})
'1 2 jack 12'
'{colors[0]} {colors[1]}'.format(colors=('RED', 'GREEN'))
'RED GREEN'
指定用於格式化 Python 字串中的參考目標的函式
在正常情況下,Python 字串中的取代欄位所參考的目標物件的__format__
方法會被呼叫,該方法的傳回值會代替取代欄位。如果希望呼叫其他函式,那麽需要在取代欄位中書寫!
,比如,!s
會呼叫 Python 的str
的建構子(建構函式)來格式化目標物件,!r
會呼叫 Python 的repr
函式,!a
會呼叫 Python 的ascii
函式。
Python 物件的 __format__ 方法可能傳回其他方法的傳回值
Python 物件的__format__
方法可能會直接或間接呼叫該物件的其他方法(比如__str__
),並傳回該方法的傳回值。
Python 的 ascii 函式與 repr 函式的區別
Python 的ascii
和repr
函式的傳回值是類似的,只不過在ascii
函式的傳回值中,非 ASCII 字元將被轉換為其對應的編碼值。
在下面的範例中,Python 類別Data
定義了自己的方法__format__
,__str__
和__repr__
,他們將在不同的情況下被呼叫。
# 一個用於格式化的類別
class Data:
def __format__(self, format_spec):
return '__format__'
def __str__(self):
return '__str__'
def __repr__(self):
return '<物件 "Data">'
# 物件的 __format__ 方法將被呼叫
print('{}'.format(Data()))
# str 的建構子將被呼叫
print('{!s}'.format(Data()))
# repr 函式將被呼叫
print('{!r}'.format(Data()))
# ascii 函式將被呼叫
print('{0!a}'.format(Data()))
__format__
__str__
<物件 "Data">
<\u5bf9\u8c61 "Data">
Python 字串格式化中的格式規格
格式規格(Format Specification)被包含在 Python 字串的取代欄位中,用於定義如何展示取代欄位所對應的值(比如,數值或字串),其基本的格式如下。
[<alignment>][sign][z][#][0][width][group][<precision>][type]
- alignment 部分
alignment
部分用於設定對齊方式,具體請參考設定對齊方式一段。- sign 值
sign
用於設定數值符號的顯示方式,具體請參考為數值設定符號顯示方式一段。- z
z
表示將浮點數-0.
視為浮點數0.
,將複數-0j
或-0.j
視為複數(0+0j)
,將decimal.Decimal(-0.)
視為decimal.Decimal(0.)
。- # 值
#
表示為整數顯示相關首碼,比如0b
(二進位),0o
(八進位),0x
或0X
(十六進位),或者強製為浮點數和複數顯示小數點。- 0
0
表示自動新增字元0
,如果有剩余空間的話。- width 值
width
表示取代欄位占用的最小空間(長度),如果忽略他,則取代欄位的空間由其對應的值來決定。- group 值
group
為數值的分隔符,可以是底線_
或逗號,
,具體請參考為數值設定分隔符一段。- precision 部分
precision
部分通常表示數值的有效位數,具體請參考為數值設定有效位數一段。- type 值
type
用於設定數值或字串的具體呈現方式,具體請參考為數值和字串設定具體呈現方式一段。
'{:}'.format(-0.)
'-0.0'
'{:z}'.format(-0.)
'0.0'
'{:07}'.format(-1.23)
'-001.23'
'{:07}'.format('abc')
'abc0000'
'{:#b}'.format(12345)
'0b11000000111001'
'{:#}'.format(1+1j)
'(1.+1.j)'
在格式化 Python 字串時設定對齊方式
如果需要在格式化 Python 字串時設定對齊方式,那麽應該給出格式規格的alignment
部分,其格式如下。需要指出的是,對齊方式僅在可用空間足夠時有效,比如,width
指定了足夠的空間。
[fill]align
- fill 值
fill
是一個字元,用於填入取代欄位的剩余空間,預設為空格。- align 值
align
表示對齊方式,如果設定為<
(大部分情況下的預設值),則采用左對齊,如果設定為>
(數值的預設值),則采用右對齊,如果設定為=
(僅對 Python 數值型別有效,但不包含 complex 型別),則在符號(比如,-
,+
)與數位之間填入fill
所表示的字元,如果設定為^
,則采用置中對齊(如果無法完成置中,則右邊填入的字元會多於左邊填入的字元)。
'{:<10}'.format(1.23)
'1.23 '
'{: >10}'.format(1.23)
' 1.23'
'{:-^10}'.format(1.23)
'---1.23---'
'{:-^11}'.format(1.23)
'---1.23----'
'{:0=10}'.format(-1.23)
'-000001.23'
'{:=3}'.format(-1.23)
'-1.23'
'{:0=10}'.format(-1.23j)
…
ValueError: Zero padding is not allowed in complex format specifier
Python 字串格式化中的格式規格中的 0
對於格式規格的alignment
部分,如果fill
為0
,那麽等同於使用格式規格中的0
。
'{:0>5}'.format(1)
'00001'
'{:05}'.format(1)
'00001'
在格式化 Python 字串時為數值設定符號顯示方式
如果需要在格式化 Python 字串時為數值設定符號的顯示方式,那麽應該給出格式規格中的sign
。sign
僅對 Python 數值型別有效,他可以是以下幾項之一,+
表示正數應顯示正號+
,負數應顯示負號-
。-
表示負數應顯示負號-
,而正數不需要顯示符號。
(空格)表示正數前應顯示
(空格),負數應顯示負號-
。
'{:+}'.format(1.23)
'+1.23'
'{:+}'.format(-1.23)
'-1.23'
'{:-}'.format(+1.23j)
'1.23j'
'{:-}'.format(-1.23j)
'(-0-1.23j)'
'{: }'.format(1.23)
' 1.23'
'{: }'.format(-1.23)
'-1.23'
在格式化 Python 字串時為數值設定分隔符
如果需要在格式化 Python 字串時為數值設定分隔符,那麽應該給出格式規格中的group
,他可以是底線_
或逗號,
。_
表示使用_
作為最終顯示的十進位數值的整數部分的千位分隔符,或使用_
作為最終顯示的其他進位數值的整數部分的四位分隔符(每四個數位插入一個分隔符)。,
表示使用,
作為最終顯示的十進位數值的整數部分的千位分隔符。
'{:_}'.format(1234567.89)
'1_234_567.89'
'{:_X}'.format(123456789)
'75B_CD15'
'{:_b}'.format(123456789)
'111_0101_1011_1100_1101_0001_0101'
'{:_}'.format(123456789.12345j)
'123_456_789.12345j'
'{:,}'.format(-123456789.12345j)
'(-0-123,456,789.12345j)'
在格式化 Python 字串時為數值設定有效位數
如果需要在格式化 Python 字串時為數值設定有效位數,那麽應該給出格式規格中的precision
部分,其格式如下。如果取代欄位所對應的數值的有效位數超出了限製,那麽數值將被拾入。
.prec
- prec 值
prec
為數值有效位數,當格式規格中的type
為f
,F
,e
或E
時,有效位數是指小數點後的位數(將自動補0
)。當格式規格中的type
為g
,G
或被忽略時,有效位數是指小數點前後的所有位數(不會自動補0
)。
'{:.5f}'.format(1)
'1.00000'
'{:.5f}'.format(1.23456789)
'1.23457'
'{:.5f}'.format(1.23j)
'0.00000+1.23000j'
'{:.5e}'.format(-0xABC123)
'-1.12561e+07'
'{:.5g}'.format(1.2)
'1.2'
'{:.5g}'.format(1234-123456j)
'1234-1.2346e+05j'
'{:.5}'.format(1234-123456j)
'(1234-1.2346e+05j)'
'{:.6}'.format(111111.)
'1.11111e+05'
Python 字串格式化中的格式規格中的 precision 部分可以限製字串長度
在 Python 字串的格式化中,雖然格式規格中的precision
部分通常用於限製數值的有效位數,但他同樣可以用於限製字串的長度。
'{:.3}'.format('Hello')
'Hel'
在格式化 Python 字串時為數值和字串設定具體呈現方式
在格式化 Python 字串的過程中,通過指定格式規格中的type
,你可以為取代欄位對應的數值或字串設定具體的呈現方式。
對於整數數值,type
擁有以下取值,b
表示將數值顯示為二進位格式,o
表示將數值顯示為八進位格式,d
(預設值)表示將數值顯示為十進位格式,x
表示將數值顯示為十六進位格式,其中字母為小寫,X
同樣表示將數值顯示為十六進位格式,但字母為大寫。n
與d
類似,但n
會根據目前區域設定來決定是否插入數值分隔符。c
表示將數值轉換為對應的 Unicode 字元。
'{:b}'.format(123)
'1111011'
'{:#x}'.format(0xA1B1C1)
'0xa1b1c1'
'{:c}'.format(65)
'A'
對於浮點數,複數或型別為decimal.Decimal
的數值,type
擁有以下取值。需要指出,這些取值同樣可用於整數,但在此之前整數(int
)會被轉換為浮點數(float
)。
e
表示將數值顯示為科學運算質,此時格式規格中的precision
表示小數點後的位數,如果未指定precision
,則有效位數預設為6
或嘗試顯示完整的小數部分(對於decimal.Decimal
)。E
與e
類似,但會采用大寫字母。
f
表示將數值顯示為固定點數,此時格式規格中的precision
表示小數點後的位數,如果未指定precision
,則有效位數預設為6
或嘗試顯示完整的小數部分(對於decimal.Decimal
)。F
與f
類似,但會采用大寫字母(比如,nan
顯示為NAN
,inf
顯示為INF
)。
g
表示根據格式規格中的precision
(有效位數為0
會被視為1
)和數值的值來選擇是否使用科學運算質顯示數值,數值末尾無意義的0
和小數點會被省略(除非使用#
),如果未指定precision
,則有效位數預設為6
或嘗試顯示完整的小數部分(對於decimal.Decimal
)。G
與g
類似,但會采用大寫字母。
n
與d
類似,但n
會根據目前區域設定來決定是否插入數值分隔符。c
表示將數值轉換為對應的 Unicode 字元。%
(不適用於複數)表示以百分比的形式顯示數值,這相當於數值乘以100
並被新增了一個百分號%
。
如果沒有為浮點數或複數指定type
,那麽相當於使用了g
(但會嘗試在沒有給出有效位數時顯示完整的數值,並嘗試去掉複數的實數部分),只不過顯示結果中的固定點數的小數點後的有效位數至少為1
。如果沒有為decimal.Decimal
型別的數值指定type
,那麽相當於使用了g
或G
,具體選擇由decimal
的內容決定,你可以通過設定內容的capitals
變數來完成此目標,設定為1
(預設值)將采用G
,設定為0
將采用g
,具體形式如下。
decimal.getcontext().capitals = capitals
- capitals 值
capitals
為1
(預設值)表示采用大寫,為0
表示采用小寫。
'{:.3e}'.format(1.2)
'1.200e+00'
'{:e}'.format(-12345678j)
'-0.000000e+00-1.234568e+07j'
'{:.3f}'.format(1.23j)
'0.000+1.230j'
'{:.3g}'.format(1.234j)
'0+1.23j'
'{:%}'.format(.23)
'23.000000%'
'{:}'.format(1.23456789)
'1.23456789'
'{:}'.format(-1.)
'-1.0'
'{:}'.format(1.234j)
'1.234j'
'{:}'.format(10000000000000000000.)
'1e+19'
對於字串,type
可以是s
(預設值),通常情況下並不需要書寫他,因為這對輸出結果沒有影響。
'{:s}'.format('Hello')
'Hello'
在格式化 Python 字串時使用巢狀的取代欄位
在格式化 Python 字串時,你可以在一個取代欄位中寫入另一個取代欄位,被寫入的取代欄位通常會作為格式規格的一部分,比如,作為格式規格中的width
或sign
。
'{0:{1}}'.format(1.23456, '10')
' 1.23456'
'{0:{1}}'.format(1.23456, '.5')
'1.2346'
'{0:{c}<{l}}'.format(1.23456, c='+', l=15)
'1.23456++++++++'
程式碼
src/zh-hant/data_types/text_types/format·codebeatme/python·GitHub