1. str.format 的引入
在 Python 中,我們可以使用 +
來連線字串,在簡單情況下這種方式能夠很好的工作。但是當我們需要進行復雜的字串連線時,如果依然使用 +
來完成,不僅會使程式碼變得晦澀難懂,還會讓程式碼變得難以維護,此時這種方式就顯得力不從心了。
例如,我們想列印這樣一條記錄:
User:John has completed Action:payment at Time:13:30:00複製程式碼
如果使用加號實現,會是下面這種形式:
print "User:" + user_name + " has completed Action:" + \
action_name + " at Time:" + current_time複製程式碼
如果以後回過頭來閱讀這段程式碼,我們很難直觀看出它的輸出格式,且修改起來也相對麻煩。
我們可以換用 %
來實現:
print "User:%s has completed Action:%s at Time:%s" % \
(user_name, action_name, current_time)複製程式碼
這回程式碼變得清晰簡潔多了。
不過,Python 為我們提供了另一種簡潔優雅的實現方式,也是官方更加推薦的方式:使用 str.format()
來實現字串的格式化:
print "User:{} has completed Action:{} at Time:{}".format(
user_name, action_name, current_time)複製程式碼
str.format
既能夠用於簡單的場景,也能夠勝任複雜的字串替換,而無需繁瑣的字串連線操作。Python 的內建型別 str
和 unicode
均支援使用 str.format()
來格式化字串。
我們接下來就詳細地討論 str.format()
的具體用法。
2. str.format 基本語法
格式化字串使用花括號 {}
來包圍替換欄位,也就是待替換的字串。而未被花括號包圍的字元會原封不動地出現在結果中。
2.1. 使用位置索引
以下兩種寫法是等價的:
"Hello, {} and {}!".format("John", "Mary")
"Hello, {0} and {1}!".format("John", "Mary")複製程式碼
花括號內部可以寫上目標字串的索引,也可以省略。如果省略,則按 format
括號裡的目標字串順序依次替換。
2.2. 使用關鍵字索引
除了通過位置來指定目標字串,我們還可以通過關鍵字來指定它。
例如:
"Hello, {boy} and {girl}!".format(boy="John", girl="Mary")複製程式碼
使用關鍵字索引的好處是,我們無需關心引數的位置,且字串的最終結果能夠一目瞭然。在以後的程式碼維護中,我們能夠快速地修改對應的引數,而不用對照字串挨個去尋找相應的引數。
注意:如果字串本身含有花括號,則需要將其重複兩次來轉義。例如,字串本身含有 {
,為了讓 Python 知道這是一個普通字元,而不是用於包圍替換欄位的花括號,我們只需將它改寫成 {{
即可。
3. str.format 高階語法
str.format
非常強大,足以完成日常工作中遇到的格式化輸出。熟練掌握該方法,能夠為以後的字串處理打好基礎,還能節省不少時間。
3.1. 訪問引數的屬性或元素
在使用 str.format
來格式化字串時,我們通常將目標字串作為引數傳遞給 format
方法。實際上,我們還可以在格式化字串中訪問引數的某個屬性或某個元素:
"My car is {0.color}.".format(black_car)
"The first student is {student[0]}.".format(student=stu_list)
"John is {d[john]} years old.".format(d=age_dict)複製程式碼
3.2. 引數輸出轉換
引數的字串輸出,預設是由其自身的 __format__
方法來實現的。也就是說,Python 使用引數的 __format__
輸出來取代替換欄位。如果我們想呼叫 str()
或 repr()
來轉換引數,可以通過新增 轉換標誌 來實現:
# call str() on argument
"It's a {0!s}."
#call repr() on argument
"We can get info from {name!r}."複製程式碼
4. str.format 一般形式
格式化字串的一般形式如下:
"... {field_name!conversion:format_spec} ..."複製程式碼
從上面的程式碼可以看到,格式化字串可分為 field_name、conversion、format_spec 三部分,分別對應替換欄位名稱(索引)、轉換標誌、格式描述。其中,欄位名稱是必選的,而後兩者是可選的。轉換標誌緊跟在英文感嘆號後面,而格式描述緊跟在英文冒號後面。
前面已經提到過,欄位名稱既可是位置索引,也可是關鍵字索引。欄位名稱後面可以通過點來訪問屬性,或通過方括號來訪問元素。
在這裡,我們重點看一下格式描述(format_spec)這一項。
格式描述中含有6個選項,分別是 fill、align、sign、width、precision、type。
它們的位置關係如下:
[[fill]align][sign][#][0][width][,][.precision][type]複製程式碼
fill
可以是任意字元,預設為空格。
align
僅當指定最小寬度時有效。
<
左對齊(預設選項)>
右對齊=
僅對數字有效;將填充字元放到符號與數字間,例如+0001234
^
居中對齊
sign
僅對數字有效
+
所有數字均帶有符號-
僅負數帶有符號(預設選項)
'#'
只對整數有效
自動在二進位制、八進位制、十六進位制數值前新增對應的 0b
、0o
、 0x
。
','
自動在每三個數字之間新增 ,
分隔符。
width
十進位制數字,定義最小寬度。如果未指定,則由內容的寬度來決定。
如果沒有指定對齊方式(align),那麼可以在 width
前面新增一個0來實現自動填充0,等價於 fill
設為 0
並且 align
設為 =
。
precision
用於確定浮點數的精度,或字串的最大長度。不可用於整型數值。
type
確定引數型別,預設為 s
,即字串。
整數輸出型別:
- b:以二進位制格式輸出
- c:將整數轉換成對應的 unicode 字元
- d:以十進位制輸出(預設選項)
- o:以八進位制輸出
- x:以十六進位制小寫輸出
- X:以十六進位制大寫輸出
- n:與 d 相同,但使用當前環境的分隔符來分隔每3位數字
十進位制浮點數輸出型別:
- e:指數標記;使用科學計數法輸出,用e來表示指數部分,預設
precision
為6 - E:與 e 相同,但使用大寫 E 來表示指數部分
- f:以定點形式輸出數值,預設
precision
為6 - F:與 f 相同
- g:通用格式;對於給定的
precision
p >= 1,取數值的p位有效數字,並以定點或科學計數法輸出(預設選項) - G:通用格式;與 g 相同,當數值過大時使用 E 來表示指數部分
- n:與 g 相同,但使用當前環境的分隔符來分隔每3位數字
- %:百分比標記;使用百分比的形式輸出數值,同時設定 f 標記