---
title: String Format in Python
description: Introduction to 4 ways of formatting string in Python.
tags: python, fstring, percent_string, string_format
GA: UA-206161787-1
lang: zh
---
###### tags: `yt` `python`
# String Format in Python
## 什麼是String Format?
舉例而言,我們在看YouTube時,在影片的下方都會顯示影片的標題以及影片發布的日期,而這些文字在每部影片中的格式都是一樣的,像是`xx小時前`之類的,有改動的地方只有`xx`,剩下的部分是不變的。這種生成固定格式字串的過程,我們就稱之為String Format。
## 4種方法
下面我們透過同一個例子來示範這四種常見的的方法。
[完整程式碼](https://colab.research.google.com/drive/1pZNhX48pTOxv1B9_crGjkO6bzhf7ZQJr?usp=sharing)
| # | Method | Support |
| --- | ------------ | ------------ |
| 1 | `+` 串接 | all versions |
| 2 | %-string | all versions |
| 3 | str.format() | >= python2.6 |
| 4 | f-string | >= python3.6 |
---
> 我們的目標是要印出標題與發布的日期。
Setup:
```python=
from datetime import datetime
title = "Python EP 0"
timestamp = datetime.now()
```
Output:
```
Title: Python EP 0, Posted on 8/23
```
### 1. `+` 串接
第一種方法是透過`+`直接把各個字串組合在一起。
```python=
print("Title: " + title + ", Posted on " + str(timestamp.month) + "/" + str(timestamp.day))
```
這種方法很直觀,但要注意,串接在一起的變數都必須是字串,像這邊我們就得把`Timestamp`中的月份與日期透過內建的`str`函式,把他們從`int`轉成`str`,這樣他們才可以正確地被串接在一起。
### 2. %-string
第二種方法是透過`%-string`,早期的Python就有支援類似C語言的`%-string`語法。使用的方法是,在我們想要替換的位置打上`%s`來標記,隨後透過`%`的Operator傳入一個含有目標字串的`Tuple`,注意,傳入的`Tuple` 必須包含所有要被置換的變數,個數不能多也不能少。像這邊我們有三個`%s`的placeholder,那就得傳入三個變數,分別是`title`和`timestamp`的月份及日期。
```python=
print("Title: %s, Posted on %s/%s" % (title, timestamp.month, timestamp.day))
```
### 3. str.format()
第三種方法是呼叫string中foramt的函式,這種方法在Python2.6之後開始支援,使用起來與`%-string`相似,他用大括號(`{}`)來標記要取代的位置,再透過呼叫`format()`的函式,傳入要取代的實際內容。此外,它提供了許多進階的功能,像是能為傳入的變數命名,並且在直接在字串中存取物件的屬性(Attribute)。像這邊,我們就標記並命名了三個要取代的地方,直接在大括號中存取`timestamp`的月份與日期。
```python=
print("Title: {t}, Posted on {ts.month}/{ts.day}".format(t=title, ts=timestamp))
```
### 4. f-string
最後一種方法稱為`f-string`,這在Python3.6之後才開始支援。使用的方法是,在定義字串的引號前,加上小寫或是大寫的`f`,接著與第三種呼叫`str.format()`相似,也是用大括號表示要取代的位置,但是他可以直接存取變數的名稱,而不需要再把對應的變數傳入。像這邊,我們可以在`f-string`中存取要顯示的變數`{title}`以及`{timestamp}`,在存取的同時,又可以利用冒號(`:%-m/%d`)來格式化顯示的日期。
```python=
print(f"Title: {title}, Posted on {timestamp:%-m/%d}")
```
## 我應該要用哪個?
首選是`f-string`,目前大部分的平台都已支援Python3.6+的版本了,`f-string`繼承了前面幾種方法的優點,兼顧程式碼的可讀性,即使是較長的格式化字串,讀者也能一眼就能看出這個位置要替換的目標是哪個變數。更重要的是,`f-string`也是這四種方法裡面,建構字串的速度最快的。
這邊我們分別對四個方法跑一百萬次,看看彼此之間速度的差異。
```python=
import timeit
ITERATIONS = 1_000_000
name = "John Doe"
age = 30
# +
plus_string_elapsed = timeit.timeit(lambda: name + " is " + str(age) + ".", number=ITERATIONS)
# Percent string
percent_string_elapsed = timeit.timeit(lambda: "%s is %s." % (name, age), number=ITERATIONS)
# str.format()
str_format_elapsed = timeit.timeit(lambda: "{} is {}.".format(name, age), number=ITERATIONS)
# f-string
f_string_elapsed = timeit.timeit(lambda: "{name} is {age}.", number=ITERATIONS)
result = (
f"plus string: {plus_string_elapsed:.3} s\n"
f"percent string: {percent_string_elapsed:.3} s\n"
f"str_format: {str_format_elapsed:.3} s\n"
f"f-string: {f_string_elapsed:.3} s"
)
print(result)
```
結果
```
plus string: 0.449 s
percent string: 0.373 s
str_format: 0.427 s
f-string: 0.0897 s
```
## 後記
對於每個方法更詳細的使用說明以及其中的雷,可以參考我在Colab上的[互動式範例](https://colab.research.google.com/drive/1pZNhX48pTOxv1B9_crGjkO6bzhf7ZQJr?usp=sharing)。