幾種不同 Python String Formatting 的使用情境

經驗法則

Python 有好幾種 string formatting 的作法,我個人決定使用情境的經驗法則如下:

語法回顧

Real Python 有篇簡介這幾種用法在語法上的差別,寫得簡單易懂、條理分明。想要複習語法的不妨一讀。

PEP 3101 陳述了除了 % operator of strings 與 the string Template module 以外,當初為什麼再創造其他種 string formatting 的方式。

str.formatf-string 的官方文件則可分別在 string librarylexical analysis 的章節中查閱到。

printf-style 使用情境的理由

printf-style 的 % 本質上是一個 operator ,所以在實做與變化上面就會受 operator 本質限制。另外這類相對早期的實做,也有一些沒完全支援(相對新的)資料結構的情況下,所引發的不預期行為。

反過來說也有可能受惠於是 operator 這件事情,例如在某些情境下,比起其他的 string formatting 方式,有一些最佳化效能的好處。例如這篇 logging performance 所陳述的例子[1]。

[1] 感謝 TP 當初幫我 code review 時所分享的案例

跨 distro 的例子

很多 Linux 發布版本( Distribution/Distro )採用 python 作為 glue language ,而該 distro 發行時,通常會綁訂了某個版本的 python 。舉例來說,如果今天有一個套件想要同時支援 Ubuntu 16.04 (預設 python3 版本是 3.5 ) 與 Ubuntu 20.04 (預設 python3 版本是 3.8 ;並且預設「沒有」 python2 )[1],我大概不會想要用 python 3.6 才開始有的 f-string 。

[1] 使用 rmadison 直接查閱各 Ubuntu disto archive 裡對應到的 python3 版本

$ rmadison python3
 python3 | 3.2.3-0ubuntu1   | precise         | all
 python3 | 3.2.3-0ubuntu1.2 | precise-updates | amd64, armel, armhf, i386, powerpc
 python3 | 3.4.0-0ubuntu2   | trusty          | amd64, arm64, armhf, i386, powerpc, ppc64el
 python3 | 3.5.1-3          | xenial          | amd64, arm64, armhf, i386, powerpc, ppc64el, s390x
 python3 | 3.6.5-3          | bionic          | amd64, arm64, armhf, i386, ppc64el, s390x
 python3 | 3.6.7-1~18.04    | bionic-updates  | amd64, arm64, armhf, i386, ppc64el, s390x
 python3 | 3.8.2-0ubuntu2   | focal           | amd64, arm64, armhf, i386, ppc64el, riscv64, s390x
 python3 | 3.8.6-0ubuntu1   | groovy          | amd64, arm64, armhf, i386, ppc64el, riscv64, s390x
 python3 | 3.9.4-1          | hirsute         | amd64, arm64, armhf, i386, ppc64el, riscv64, s390x
 python3 | 3.9.4-1          | impish          | amd64, arm64, armhf, i386, ppc64el, riscv64, s390x

你使用 string formatting 的考量是什麼?

There should be one-- and preferably only one --obvious way to do it.

- PEP-20, the Zen of Python

String formatting 或許是 python 中幾個「好像」跟這個概念比較衝突的例子。你選擇的 string formatting 方式,考量又是什麼呢?歡迎與我分享。