如何在Python 3中使用字符串格式化程序

###介紹

Python的str.format()方法是string類別中的一個功能,允許您進行變數替換和值格式化。這讓您能夠透過位置格式化在一個字串中串接元素。

本教程將指導您使用Python中格式化器的一些常見用法,這可以幫助使您的代碼和程序更具可讀性和用戶友好性。

先決條件

您應該已經安裝了Python 3並在您的計算機或服務器上設置了編程環境。如果您尚未設置編程環境,可以參考安裝和設置指南,選擇一個適合您操作系統的本地編程環境或者適用於您的服務器的編程環境(Ubuntu、CentOS、Debian等)

##使用格式化器

格式化程序通過在字符串中放置一個或多個替換字段或佔位符 —— 由一對大括號 {} 定義 —— 並調用 str.format() 方法來工作。您將通過該方法傳遞您想要與字符串串聯的值。當您運行程序時,這個值將通過在與佔位符相同位置傳遞。

讓我們打印一個使用格式化程序的字符串:

資訊: 要跟隨本教程中的示例代碼,請在您的本地系統上運行 python3 命令以打開 Python 交互式外殼。然後,您可以通過在 >>> 提示後添加它們來複製、粘貼或編輯示例。

print("Sammy has {} balloons.".format(5))
Output
Sammy has 5 balloons.

在上面的示例中,我們使用一對大括號作為佔位符構造了一個字符串:

"Sammy has {} balloons."

然後,我們添加了 str.format() 方法,並將整數 5 的值傳遞給該方法。這將值 5 放入原始字符串中的大括號位置:

Sammy has 5 balloons.

我們還可以將一個變量賦值為具有格式化程序佔位符值的字符串:

open_string = "Sammy loves {}."
print(open_string.format("open source"))
Output
Sammy loves open source.

在這個第二個示例中,我們將字符串 "open source" 與較大的字符串串聯起來,替換了原始字符串中的大括號。

Python 中的格式化程序允許您使用大括號作為您將通過 str.format() 方法傳遞的值的佔位符。

##使用具有多個佔位符的格式化程序

您可以在使用格式化程序时使用多对花括号。如果我们想要在上述句子中添加另一个变量替换,我们可以通过添加第二对花括号并将第二个值传递给方法来实现:

new_open_string = "Sammy loves {} {}."                      #2 {}占位符
print(new_open_string.format("open-source", "software"))    #通过逗号分隔,将2个字符串传递给方法
Output
Sammy loves open-source software.

要添加另一个替换,我们在原始字符串中添加了第二对花括号。然后,我们通过逗号将两个字符串传递给str.format()方法。

按照相同的语法,我们可以添加额外的替换:

sammy_string = "Sammy loves {} {}, and has {} {}."                      #4 {}占位符
print(sammy_string.format("open-source", "software", 5, "balloons"))    #将4个字符串传递给方法
Output
Sammy loves open-source software, and has 5 balloons.

sammy_string中,我们添加了4对花括号作为变量替换的占位符。然后,我们传递了4个值给str.format()方法,混合了字符串和整数数据类型。这些值都用逗号分隔。

##使用位置和关键字参数重新排序格式化程序

当我们将花括号留空而不带任何参数时,Python将按顺序替换通过str.format()方法传递的值。正如我们所见,到目前为止,使用两对空花括号并通过两个值传递的格式化程序构造将如下所示:

print("Sammy the {} has a pet {}!".format("shark", "pilot fish"))
Output
Sammy the shark has a pet pilot fish!

第一对花括号被替换为"shark"的字符串值,第二对被替换为"pilot fish"的字符串值。

存在於方法內的數值看起來像這樣:

("shark", "pilot fish")

它們基本上是元組數據類型,元組中包含的每個單獨數值可以通過其索引號進行調用,索引號從索引號0開始。

我們可以將這些索引號傳遞到原始字符串中作為佔位符:

print("Sammy the {0} has a pet {1}!".format("shark", "pilot fish"))

在上面的例子中,輸出將是在不將索引號傳遞到大括號中時我們獲得的內容,因為我們按順序調用元組中的數值:

Output
Sammy the shark has a pet pilot fish!

但是,如果我們通過佔位符的參數來反轉索引號,我們可以反轉傳遞到字符串中的數值:

print("Sammy the {1} has a pet {0}!".format("shark", "pilot fish"))
Output
Sammy the pilot fish has a pet shark!

如果在具有索引位置0和1的元組中調用索引號為2的索引號,則您正在調用超出範圍的值。當您調用超出範圍的索引號時,您將收到一條錯誤消息:

print("Sammy the {2} has a pet {1}!".format("shark", "pilot fish"))
Output
IndexError: tuple index out of range

我們看到的錯誤消息是指元組僅在索引號0和1處有數值,因此將索引號2放在超出範圍之外。

讓我們添加幾個更多的佔位符和更多的數值傳遞給它們,這樣我們就可以更好地理解如何重新排序格式化程序。首先,這是一個具有四個佔位符的新字符串:

print("Sammy is a {}, {}, and {} {}!".format("happy", "smiling", "blue", "shark"))
Output
Sammy is a happy, smiling and blue shark!

如果沒有參數,則傳遞給str.format()方法的值將按順序連接到字符串中。

元組中包含的字符串值對應以下索引號:

“happy” “smiling” “blue” “shark”
0 1 2 3

讓我們使用數值的索引來改變它們在字串中出現的順序:

print("Sammy is a {3}, {2}, and {1} {0}!".format("happy", "smiling", "blue", "shark"))
Output
Sammy is a shark, blue, and smiling happy!

由於我們從索引號碼 3 開始,我們首先呼叫了 "shark" 的最後一個值。其他作為參數包含的索引號碼會改變原始字串中單字出現的順序。

除了位置參數,我們還可以引入關鍵字參數,透過它們的關鍵字名稱來呼叫:

print("Sammy the {0} {1} a {pr}.".format("shark", "made", pr = "pull request"))
Output
Sammy the shark made a pull request.

這個範例展示了使用關鍵字參數與位置參數一起使用的情況。我們可以在位置參數旁邊填入關鍵字參數 pr,並且可以移動這些參數來改變結果字串:

print("Sammy the {pr} {1} a {0}.".format("shark", "made", pr = "pull request"))
Output
Sammy the pull request made a shark.

與字串格式化程式一起使用的位置和關鍵字參數讓我們能夠更多地控制通過重新排序來操作我們的原始字串。

##指定類型

我們可以在大括號內包含更多參數。我們將使用格式代碼語法 {field_name:conversion},其中 field_name 指定要傳遞給 str.format() 方法的引數的索引號碼,就像我們在重新排序部分中所述的那樣,而 conversion 則是您與格式化程式一起使用的資料類型的轉換代碼。

轉換類型指的是 Python 使用的單個字符類型代碼。這裡我們將使用的代碼是 s 表示字符串,d 表示顯示十進制整數(以10為底),f 表示我們將使用它來顯示帶有小數位的浮點數。您可以通過 Python 3 官方文檔了解更多關於 格式規範迷你語言 的信息。

讓我們看一個示例,我們有一個整數通過方法傳遞,但希望通過添加 f 轉換類型參數將其顯示為浮點數:

print("Sammy ate {0:f} percent of a {1}!".format(75, "pizza"))
Output
Sammy ate 75.000000 percent of a pizza!

我們使用了 {field_name:conversion} 的語法來替換第一個大括號中的字段以輸出浮點數。第二個大括號僅使用第一個參數 {field_name}

在上面的示例中,小數點後面顯示了很多數字,但您可以對其進行限制。當您為浮點數值指定 f 時,還可以通過在小數點後面加上一個句點 . ,然後是您想要包括的小數位數字來指定該值的精度。

如果 Sammy 吃掉了 75.765367% 的披薩,但我們不需要高精度,我們可以通過在轉換類型 f 前添加 .3 來將小數點後的位數限制為3:

print("Sammy ate {0:.3f} percent of a pizza!".format(75.765367))
Output
Sammy ate 75.765 percent of a pizza!

如果我們只想要一個小數點,我們可以這樣重寫字符串和方法:

print("Sammy ate {0:.1f} percent of a pizza!".format(75.765367))
Output
Sammy ate 75.8 percent of a pizza!

請注意,修改精度將導致數字四捨五入。

雖然我們將沒有小數位的數字顯示為浮點數,但如果我們嘗試使用d轉換類型將浮點數轉換為整數,將會收到一個錯誤:

print("Sammy ate {0:d} percent of a pizza!".format(75.765367))
Output
ValueError: Unknown format code 'd' for object of type 'float'

如果你希望不顯示小數位,可以這樣編寫你的格式化程序:

print("Sammy ate {0:.0f} percent of a pizza!".format(75.765367))
Output
Sammy ate 76 percent of a pizza!

這將不會將浮點數轉換為整數,而是限制小數點後顯示的位數。

##填充變量替換

因為佔位符是替換字段,你可以通過額外的參數增加字段大小來填充或在元素周圍創建空間。當我們需要在視覺上組織大量數據時,這很有用。

我們可以在大括號的冒號:後添加一個數字來指示字段大小(以字符為單位):

print("Sammy has {0:4} red {1:16}!".format(5, "balloons"))
Output
Sammy has 5 red balloons !

在上面的例子中,我們給數字5設置了4個字符的字段大小,並給字符串balloons設置了16個字符的字段大小(因為它是一個長字符串)。

正如我們所看到的,字符串默認左對齊在字段內,而數字右對齊。你可以通過在冒號後面放置對齊代碼來修改這一點。<將文本左對齊在字段內,^將文本居中在字段內,>將文本右對齊。

讓我們將數字左對齊並將字符串居中:

print("Sammy has {0:<4} red {1:^16}!".format(5, "balloons"))
Output
Sammy has 5 red balloons !

現在我們看到 5 是左對齊的,提供了在 red 前方的欄位空間,而 balloons 則是在其欄位中央,左右有空間。

默認情況下,當我們使用格式化器擴大欄位時,Python 將用空白字符填充欄位。我們可以通過在冒號後直接指定我們想要的字符來修改它:

print("{:*^20s}".format("Sammy"))
Output
*******Sammy********

我們正在接受傳遞給 str.format() 的字符串,索引位置為 0,因為我們沒有另外指定,包括冒號,並指定我們將使用 * 而不是空格來填充欄位。我們使用 ^ 將字符串居中,指定欄位大小為 20 個字符,並且還指示我們正在使用字符串轉換類型,包括 s

我們可以將這些參數與之前使用的其他參數結合使用:

print("Sammy ate {0:5.0f} percent of a pizza!".format(75.765367))
Output
Sammy ate 76 percent of a pizza!

在大括號內的參數中,我們指定了浮點數的索引字段號,包括了冒號,指示了欄位號的大小並包含了小數點,寫入了小數點後的位數,然後指定了 f 的轉換類型。

## 使用變量

到目前為止,我們已經將整數、浮點數和字符串傳遞給了 str.format() 方法,但我們也可以通過該方法傳遞變量。這與任何其他變量的使用方式相同。

nBalloons = 8
print("Sammy has {} balloons today!".format(nBalloons))
Output
Sammy has 8 balloons today!

我們可以將變量用於原始字符串和傳遞到方法中的內容:

sammy = "Sammy has {} balloons today!"
nBalloons = 8
print(sammy.format(nBalloons))
Output
Sammy has 8 balloons today!

變數可以很容易地替換我們格式化語法構造的每個部分。這使得當我們接收用戶生成的輸入並將這些值分配給變數時更容易使用。

##使用格式化程序組織數據

當我們使用格式化程序以視覺方式組織大量數據時,可以看到它們的優勢。如果我們向用戶展示數據庫,使用格式化程序來增加字段大小和修改對齊方式可以使您的輸出更易讀。

讓我們看一個在Python中打印出ii*ii*i*i範圍為3到12的典型for循環

for i in range(3,13):
    print(i, i*i, i*i*i)
Output
3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 11 121 1331 12 144 1728

雖然輸出已經以一種方式組織好了,但數字溢出到彼此的列中,使得輸出的底部變得不太易讀。如果您正在處理一個包含許多小數和大數的更大數據集,這可能會造成問題。

讓我們使用格式化程序為這些數字提供更多的空間:

for i in range(3,13):
    print("{:3d} {:4d} {:5d}".format(i, i*i, i*i*i))

在這裡,在我們的大括號中,我們沒有添加索引號的字段名,而是從冒號開始,後面跟著字段大小的數字,以及d轉換類型,因為我們正在處理整數。在這個例子中,我們為每個預期輸出的大小做了適應,根據最大可能的數字大小,為每個輸出給予了2個額外的字符空間,所以我們的輸出看起來像這樣:

Output
3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 11 121 1331 12 144 1728

我們可以指定一個一致的字段大小數字,以便有均勻的列,確保我們考慮了更大的數字:

for i in range(3,13):
    print("{:6d} {:6d} {:6d}".format(i, i*i, i*i*i))
Output
3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 11 121 1331 12 144 1728

我們還可以通過添加<^>來操作列的對齊方式,將d更改為f以添加小數位數,更改字段名索引號,等等,以確保我們顯示數據的方式符合我們的要求。

##結論

使用變量替換的格式化器可以是串聯字符串和組織值和數據的有效方法。格式化器代表一種基本但不具描述性的將變量替換傳遞到字符串中的方式,對於確保輸出可讀性和用戶友好性非常有用。

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-string-formatters-in-python-3