使用 Python 格式化字元串

使用 Python 格式化字元串

來自專欄極光日報16 人贊了文章

簡評:Python 之禪中有一段是「There should be one– and preferably only one –obvious way to do it.」翻譯過來就是「找到一種或唯一的一種解決方案去解決問題」,但在 Python 中卻有四種主要的字元串格式化方法。

先讓我們假設有以下變數:

基於這些變數,希望生成包含簡單錯誤消息的輸出字元串:

Hey Bob, there is a 0xbadc0ffee error!

#1 舊式字元串格式化( 運算符)

Python 字元串具有獨特的內置操作,可以使用 % 運算符進行訪問,這樣可以非常輕鬆地進行簡單的位置格式化。 如果你曾在 C 語言中使用過 printf 風格的函數,那麼你將立即認識到它是如何工作的。 下面一個簡單的例子:

我在這裡使用 %s 格式符告訴 Python 在哪裡替換 name 的值,還有其他格式符可供控制輸出格式。例如,可以將數字轉換為十六進位表示法或添加填充空格以生成格式良好的表格和報告。在這裡,可以使用%x格式符將整型值轉換為字元串並將其表示為十六進位數:

如果要在單個字元串中進行多個替換,則「舊式」字元串格式化語法會略有變化。因為%運算符只能接受一個參數,所以需要將右側變數放在元組中,如下所示:

如果將映射傳遞給%運算符,也可以在格式字元串中按名稱引用變數替換:

這使格式字元串更易於維護,並且將來更容易修改,並且不必擔心在值的傳遞的順序與格式字元串中引用值的順序是否匹配,當然,缺點是這需要打更多的字。

你一定在想為什麼這種printf格式稱為「舊式」字元串格式化,它在技術上被 Python 3 中的「新式」格式所取代。

#2 新式字元串格式化(str.format

Python 3 引入了一種新的字元串格式化方法,後來也被移植到 Python 2.7 中。這種「新式」字元串格式化擺脫了%操作符的特殊語法,並使字元串格式化的語法更加規範。現在可以通過在字元串對象上調用.format()來格式化字元串。

就像使用「舊式」格式化方法一樣,可以使用format()簡單的位置格式化:

或者,可以按名稱引用變數替換,並以任意順序使用它們。這是一個非常強大的功能,因為它允許重新排列顯示順序而不更改傳遞給format()的參數:

這也表明將int變數格式化為十六進位字元串的語法已更改。現在,需要通過添加:x後綴來傳遞格式規範,格式化字元串的語法變得更加強大,而沒有增加使用的複雜度。

#3 字元串插值 / f-Strings(Python 3.6+)

Python 3.6 添加了一種新的字元串格式化方法,稱為「formatted string literals」或「f-strings」。這種格式化字元串的新方法允許在字元串常量中使用嵌入的 Python 表達式,下面是一個簡單的例子:

正如你所看到的,這種方法是在字元串常量前加上字母「f」 —— 因此名稱為「f-strings」。這種新的格式化語法非常強大,因為可以嵌入任意 Python 表達式,甚至可以使用它進行內聯運算。看看這個例子:

formatted string literals 是一種 Python 解析器功能,可將f-strings轉換為一系列字元串常量和表達式,然後他們聯合起來構建最終的字元串。

如果你有以下包含 f-stringsgreet()函數:

當反編譯該函數並檢查幕後發生的事情時,會看到函數中的f-strings轉換為類似於以下內容的字元串:

def greet(name, question): return "Hello, " + name + "! Hows it " + question + "?"

真正的實現稍微快一點,因為它使用BUILD_STRING操作碼進行了優化。但在功能上它們是相同的:

字元串文字還支持該方法的現有格式化字元串語法str.format()。這允許解決我們在前兩節中討論過的相同格式問題:

#4模板字元串(標準庫)

這是 Python 字元串格式化的另一個工具:模板字元串,它是一種更簡單,功能更少的機制,但在某些情況下,這可能正是你所需要的。

我們來看一個簡單的greet示例:

首先我們需要從 Python 的內置string模塊導入Template類,模板字元串不是核心語言功能,由f="https://docs.python.org/3/library/string.html">string標準庫中的模塊提供。

另一個區別是模板字元串不允許格式符,因此,為了使先前的錯誤字元串示例整型生效,需要手動將錯誤編號轉換為十六進位字元串:

嗯,美滋滋

那麼應該在什麼時候使用模板字元串?在我看來,使用模板字元串的最佳時機是在處理用戶生成的格式化字元串時,由於複雜性降低,模板字元串是更安全的選擇。其他字元串格式化技術可能會給程序帶來安全漏洞,例如,格式字元串可以訪問程序中的任意變數。

結語

那麼,應該使用哪種字元串格式化方法呢?

此流程圖基於我在編寫 Python 時的經驗法則:

Python 字元串格式化經驗法則:如果格式字元串是用戶提供的,請使用模板字元串(#4)來避免安全問題。否則,如果使用的是 Python 3.6+,則使用 Literal String Interpolation / f-Strings(#3),如果不是,則使用 str.format(#2)。

原文:Python String Formatting – Real Python

擴展閱讀:

  • Python 3.7 將引入 dataclass 裝飾器
  • 簡析 Python 的 `NotImplemented`
  • Python 的 For/Else 語句
  • 使用 Python 和 Click 編寫命令行應用程序
  • Python:range 對象並不是迭代器
  • PyPI 終於支持 Markdown 了
  • 8102 年資深程序員一定要 follow 的 Python 博客/網站 Top 10

極光日報,極光開發者旗下媒體。

每天導讀三篇英文技術文章。

推薦閱讀:

《Scikit-Learn與TensorFlow機器學習實用指南》第14章 循環神經網路
Day8,os模塊,時間戳
python 壓縮 整個文件夾 壓縮到 指定路徑
python基礎-zip
Django Doc:Making queries

TAG:Python | 科技 | 計算機科學 |