URLhttps://learnscript.net/zh-hant/python/data-types/text-types/format/
    複製連結移至說明  範例

    如何格式化 Python 字串?format,format_map 方法,Formatter 類別介紹

    閱讀 17:38·字數 5293·更新 
    Youtube 頻道
    訂閱 375

    本節內容不涉及 Python 舊式 printf 風格的字串格式化,你可以檢視Python 舊式 printf 風格的字串格式化使用說明一節來了解相關資訊。

    字串格式化中的取代欄位

    對於需要進行格式化的字串,他們通常含有一些取代(格式)欄位,取代欄位由一個{}及其包含的內容組成,並會被運算結果取代。

    取代欄位可能被str型別的formatformat_map方法,格式化字串,或string模組的Formatter類別使用,以用來參考方法的參數或目前可存取的變數等內容。

    如何在格式化字串時表示大括弧自身?

    在對字串進行格式化時,{}會被解釋為取代欄位,如果要在字串中表示{}自身,那麽需要將其書寫為{{}}

    '{{}}'.format()
    '{}'

    str 型別的 format,format_map 方法

    str型別的formatformat_map方法,提供了格式化字串的功能,只需要在字串中書寫取代欄位,即可參考formatformat_map方法提供的參數。

    format(*args, **kwargs)
    format_map(mapping)

    args 參數

    可變參數args所包含的位置參數將被字串中的取代欄位參考。

    kwargs 參數

    可變參數kwargs所包含的關鍵字參數將被字串中的取代欄位參考。

    mapping 參數

    參數mapping通常是一個字典物件或通過__getitem__方法提供值的物件,這些物件提供的值將被字串中的取代欄位參考。

    在下面的範例中,我們定義了一個用於格式化的類別Data,該類別將提供姓名和年齡資訊,你需要在字串中使用{name}{age}來參考他們。

    format.py
    # 一個用於格式化的類別
    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

    格式化字串

    格式化字串是以fF為前綴的字串,此類字串可以包含取代欄位,並在其中書寫運算式,運算式的計算結果將代替取代欄位出現在字串中。

    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'

    string 模組的 Formatter 類別

    string模組的Formatter類別,同樣可用於格式化字串,該類別的執行個體方法formatvformat可實作與str型別的formatformat_map方法類似的效果。

    formatter.format(format_string, /, *args, **kwargs)

    format_string 參數

    參數format_string是需要進行格式化的字串。

    args 參數

    可變參數args所包含的位置參數將被format_string參數中的取代欄位參考。

    kwargs 參數

    可變參數kwargs所包含的關鍵字參數將被format_string參數中的取代欄位參考。

    formatter.vformat(format_string, args, kwargs)

    format_string 參數

    參數format_string是需要進行格式化的字串。

    args 參數

    參數args是一個序列物件,其包含的元素(項)將被字串中的取代欄位參考。

    kwargs 參數

    參數kwargs是一個對映物件,其包含的元素(項)將被字串中的取代欄位參考。

    import string
    f = string.Formatter()
    f.format('{name} {0}', 12, name='Jack')
    'Jack 12'
    f.vformat('{name} {0}', (12,), {'name': 'Jack'})
    'Jack 12'

    在字串中參考方法的參數

    對於str型別的formatformat_map方法,以及string模組的Formatter物件的formatvformat方法,字串中的取代欄位{}將按照出現順序參考format方法中的位置參數,第一個出現的{}參考第一個位置參數,第二個出現的{}參考第二個位置參數,以此類推。

    '{}: "{}"'.format('Jack', 'HELLO')
    'Jack: "HELLO"'

    如果需要在str型別的format方法,以及string模組的Formatter物件的formatvformat方法中參考指定位置的位置參數,那麽可以在{}中填寫位置參數的索引,0表示參考第一個位置參數。

    取代欄位不能參考不存在於 format 方法的位置參數

    對於字串中的取代欄位{},如果其包含的索引所對應的位置參數不存在,那麽例外狀況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

    如果需要在str型別的formatformat_map方法,以及string模組的Formatter物件的formatvformat方法中參考關鍵字參數,那麽可以在{}中填寫關鍵字參數的名稱。

    取代欄位不能參考不存在於 format,format_map 方法的關鍵字參數

    如果字串中的取代欄位{}所參考的關鍵字參數,並不存在於formatformat_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'

    在字串中參考方法的參數的特性

    對於str型別的formatformat_map方法,以及string模組的Formatter物件的formatvformat方法,在字串的取代欄位中書寫.attribute可以存取相關參數的特性(比如,變數,屬性等),其中attribute為特性的名稱。而書寫[key]可以間接呼叫相關參數的__getitem__方法,這意味著你可以在取代欄位中存取串列或字典的值。需要指出,在[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'

    指定用於格式化參考目標的函式

    在正常情況下,字串中的取代欄位所參考的目標物件的__format__方法會被呼叫,該方法的傳回值會代替取代欄位。如果希望呼叫其他函式,那麽需要在取代欄位中書寫!,比如,!s會呼叫str的建構子(建構函式)來格式化目標物件,!r會呼叫 Python 的repr函式,!a會呼叫 Python 的ascii函式。

    Python 物件的 __format__ 方法可能傳回其他方法的傳回值

    物件的__format__方法可能會直接或間接呼叫該物件的其他方法(比如__str__),並傳回該方法的傳回值。

    Python 的 ascii 函式與 repr 函式的區別

    Python 的asciirepr函式的傳回值是類似的,只不過在ascii函式的傳回值中,非 ASCII 字元將被轉換為其對應的編碼值。

    在下面的範例中,類別Data定義了自己的方法__format____str____repr__,他們將在不同的情況下被呼叫。

    function.py
    # 一個用於格式化的類別
    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">

    字串格式化中的格式規格

    格式規格(Format Specification)被包含在字串的取代欄位中,用於定義如何展示取代欄位所對應的值(比如,數值或字串),其基本的格式如下。

    [<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(八進位),0x0X(十六進位),或者強製為浮點數和複數顯示小數點。

    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)'

    在格式化字串時設定對齊方式

    如果需要在格式化字串時設定對齊方式,那麽應該給出格式規格的alignment部分,其格式如下。需要指出的是,對齊方式僅在可用空間足夠時有效,比如,width指定了足夠的空間。

    [fill]align

    fill 值

    fill是一個字元,用於填入取代欄位的剩余空間,預設為空格。

    align 值

    align表示對齊方式,如果設定為<(大部分情況下的預設值),則采用左對齊,如果設定為>(數值的預設值),則采用右對齊,如果設定為=(僅對數值型別有效,但不包含 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部分,如果fill0,那麽等同於使用格式規格中的0

    '{:0>5}'.format(1)
    '00001'
    '{:05}'.format(1)
    '00001'

    在格式化字串時設定數值的符號顯示方式

    如果需要在格式化字串時為數值設定符號的顯示方式,那麽應該給出格式規格中的signsign僅對數值型別有效,他可以是以下幾項之一,+表示正數應顯示正號+,負數應顯示負號--表示負數應顯示負號-,而正數不需要顯示符號。 (空格)表示正數前應顯示 (空格),負數應顯示負號-

    '{:+}'.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'

    在格式化字串時設定數值的分隔符

    如果需要在格式化字串時為數值設定分隔符,那麽應該給出格式規格中的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)'

    在格式化字串時設定數值的精確度

    如果需要在格式化字串時為數值設定精確度,那麽應該給出格式規格中的precision部分,其格式如下。如果取代欄位所對應的數值的精確度超出了限製,那麽數值將被拾入。

    .prec

    prec 值

    prec為數值精確度,當格式規格中的typefFeE時,精確度是指小數點後的位數(將自動補0)。當格式規格中的typegG或被忽略時,精確度是指小數點前後的所有位數(不會自動補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'

    格式規格中的 precision 部分可以限製字串長度

    在字串的格式化中,雖然格式規格中的precision部分通常用於限製數值的精確度,但他同樣可以用於限製字串的長度。

    '{:.3}'.format('Hello')
    'Hel'

    在格式化字串時設定數值和字串的具體呈現方式

    在格式化字串的過程中,通過指定格式規格中的type,你可以為取代欄位對應的數值或字串設定具體的呈現方式。

    對於整數數值,type擁有以下取值,b表示將數值顯示為二進位格式,o表示將數值顯示為八進位格式,d(預設值)表示將數值顯示為十進位格式,x表示將數值顯示為十六進位格式,其中字母為小寫,X同樣表示將數值顯示為十六進位格式,但字母為大寫。nd類似,但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)。Ee類似,但會采用大寫字母。

    f表示將數值顯示為固定點數,此時格式規格中的precision表示小數點後的位數,如果未指定precision,則精確度預設為6或嘗試顯示完整的小數部分(對於decimal.Decimal)。Ff類似,但會采用大寫字母(比如,nan顯示為NANinf顯示為INF)。

    g表示根據格式規格中的precision(精確度為0會被視為1)和數值的值來選擇是否使用科學計數法顯示數值,數值末尾無意義的0和小數點會被省略(除非使用#),如果未指定precision,則精確度預設為6或嘗試顯示完整的小數部分(對於decimal.Decimal)。Gg類似,但會采用大寫字母。

    nd類似,但n會根據目前區域設定來決定是否插入數值分隔符。c表示將數值轉換為對應的 Unicode 字元。%(不適用於複數)表示以百分比的形式顯示數值,這相當於數值乘以100並被新增了一個百分號%

    如果沒有為浮點數或複數指定type,那麽相當於使用了g(但會嘗試在沒有給出精確度時顯示完整的數值,並嘗試去掉複數的實數部分),只不過顯示結果中的固定點數的小數點後的精確度至少為1。如果沒有為decimal.Decimal型別的數值指定type,那麽相當於使用了gG,具體選擇由decimal的上下文決定,你可以通過設定上下文的capitals變數來完成此目標,設定為1(預設值)將采用G,設定為0將采用g,具體形式如下。

    decimal.getcontext().capitals = capitals

    capitals 值

    capitals1(預設值)表示采用大寫,為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'

    在格式化字串時使用巢狀的取代欄位

    在格式化字串時,你可以在一個取代欄位中寫入另一個取代欄位,被寫入的取代欄位通常會作為格式規格的一部分,比如,作為格式規格中的widthsign

    '{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