Python 基本語法 – print() 與格式化輸出(f‑string、format()、%)
簡介
在寫程式時,將資訊呈現在螢幕上是最常見的需求之一。Python 提供了功能強大的 print() 函式,配合不同的字串格式化方式,讓我們能夠快速、彈性地產生易讀的輸出。
不論是除錯、日誌記錄,或是建立使用者介面(CLI)訊息,都離不開「字串插值」的技巧。掌握 print() 的用法與三大格式化手段(f‑string、str.format()、舊式 %),不只能提升程式的可讀性,也能避免常見的錯誤與效能問題。
本篇文章將從最基礎的 print() 語法說起,逐步介紹三種格式化方式的特性、適用情境與實作範例,最後彙整常見陷阱與最佳實踐,幫助初學者快速上手,同時為中級開發者提供進階的優化觀點。
核心概念
1. print() 的基本使用
print() 會把傳入的物件轉成字串,並在最後自動加上換行符號(\n)。
常見的參數包括:
| 參數 | 說明 |
|---|---|
sep |
物件之間的分隔字元,預設為空格 |
end |
結束字元,預設為換行 \n |
file |
輸出目標,預設為 sys.stdout |
flush |
是否立即刷新緩衝區 |
# 基本範例
print("Hello", "world!") # 以空格分隔
print("A", "B", "C", sep="-") # 使用 - 作為分隔符
print("No newline", end="") # 不換行,後續輸出會接在同一行
print(" - still same line")
2. f‑string(字面值插值)
Python 3.6 之後,引入了 f‑string(格式化字串常數),語法簡潔且效能優於其他方式。只要在字串前加上 f,並在大括號 {} 中直接放入變數或表達式,即可完成插值。
name = "Alice"
age = 28
# 使用 f‑string
print(f"姓名:{name},年齡:{age} 歲")
# 直接寫表達式
print(f"下一年她將是 {age + 1} 歲")
# 呼叫函式或方法
print(f"大寫姓名:{name.upper()}")
格式規範
在大括號內可加入 : 後接格式說明,例如數字、日期、寬度與對齊:
price = 1234.567
print(f"原價:{price:.2f} 元") # 兩位小數
print(f"左對齊:{price:<10.2f}") # 左對齊、寬度 10
print(f"千分位:{price:,.2f}") # 加千分位逗號
3. str.format() 方法
在 f‑string 出現前,format() 是最常用的字串格式化工具。它支援位置參數、關鍵字參數以及更複雜的格式說明。
# 位置參數
print("第一名:{}, 第二名:{}".format("Tom", "Jerry"))
# 關鍵字參數
print("使用者 {user} 的 ID 為 {id}".format(user="Bob", id=42))
# 重新排列與重複使用
template = "{0} + {0} = {1}"
print(template.format(5, 10))
同樣可以使用 : 進行格式化:
value = 0.25678
print("比例:{:.1%}".format(value)) # 顯示為百分比,保留 1 位小數
print("十六進位:{:#x}".format(255)) # 0x 前綴
4. 舊式 % 格式化(C 語言風格)
雖然已被 format() 與 f‑string 取代,但在維護舊有程式碼時仍會碰到 % 形式。它使用 佔位符(如 %s、%d、%f)以及一個元組或字典提供值。
# 基本使用
print("姓名:%s,年齡:%d" % ("Charlie", 30))
# 小數點與寬度控制
print("價格:%8.2f 元" % 123.4) # 寬度 8、保留 2 位小數
# 使用字典
data = {"city": "Taipei", "temp": 28.6}
print("城市 %(city)s,溫度 %(temp).1f°C" % data)
注意:
%只能處理少數幾種型別,且在多參數時必須使用元組或字典,較不直觀。
程式碼範例彙總
以下提供 5 個實務範例,示範不同情境下的字串格式化與 print() 設定。
# 範例 1:列印表格(使用 f‑string 與對齊)
headers = ["商品", "數量", "單價", "小計"]
items = [
("蘋果", 5, 12.3),
("香蕉", 12, 8.5),
("橘子", 3, 15.0),
]
print(f"{headers[0]:<6} {headers[1]:>4} {headers[2]:>6} {headers[3]:>8}")
print("-" * 30)
for name, qty, price in items:
subtotal = qty * price
print(f"{name:<6} {qty:>4} {price:>6.2f} {subtotal:>8.2f}")
# 範例 2:日誌訊息(使用 format() 與時間格式)
import datetime
log_template = "[{time}] {level:<8}: {msg}"
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(log_template.format(time=now, level="INFO", msg="系統啟動完成"))
# 範例 3:舊式程式碼相容(% 方式)
user = "admin"
attempts = 3
print("使用者 %s 嘗試登入 %d 次" % (user, attempts))
# 範例 4:多行輸出(print 的 end 參數)
for i in range(1, 6):
print(i, end=" → " if i < 5 else "\n")
# 輸出: 1 → 2 → 3 → 4 → 5
# 範例 5:寫入檔案(print 的 file 參數)
with open("output.txt", "w", encoding="utf-8") as f:
print("這是一行文字", file=f)
print(f"使用 f‑string 寫入:{42 * 2}", file=f)
常見陷阱與最佳實踐
| 陷阱 | 說明 | 建議的做法 |
|---|---|---|
忘記 sep 或 end |
產生多餘的空格或換行,尤其在組合多段訊息時。 | 明確設定 sep=''、end='',或使用字串拼接後一次 print()。 |
| 混用不同格式化方式 | 會讓程式碼難以閱讀,且可能產生類型不匹配錯誤。 | 統一使用 f‑string(Python ≥3.6)或 format();僅在維護舊代碼時才保留 %。 |
| 浮點數精度問題 | 直接印出浮點數會出現長小數。 | 使用格式說明(.2f、.1%)控制顯示位數。 |
| 字典/元組缺少括號 | % 佔位符使用字典或元組時,忘記加括號會拋出 TypeError。 |
確認 % 後的值是 tuple (% (a, b)) 或 dict (% {"k":v})。 |
在大量迭代中使用 print() |
每次呼叫都會寫入標準輸出,效能較差。 | 若需大量輸出,可先累積到 list,最後一次 print('\n'.join(list)),或使用 logging 模組。 |
最佳實踐:
- 優先使用 f‑string:語法簡潔、效能佳、支援直接嵌入表達式。
- 統一風格:在同一專案內選定一種格式化方式,避免混雜。
- 明確設定
sep、end:尤其在生成 CSV、表格或自訂分隔符時。 - 使用
logging替代print():在正式專案中,日誌等級與輸出目的地更具彈性。 - 避免硬編碼寬度:若需動態調整,考慮使用
textwrap或tabulate等套件。
實際應用場景
命令列工具(CLI)
- 利用 f‑string 快速組合指令說明、參數回饋。
print(..., end='')可製作進度條或動態更新的輸出。
資料分析報告
- 使用
format()或 f‑string 產生統計摘要(平均值、標準差)表格。 - 結合
pandas.DataFrame.to_string(),自訂列寬與對齊方式。
- 使用
系統日誌(Logging)
logging.info(f"使用者 {user_id} 登入成功")讓訊息更具可讀性。- 若仍需
print(),可先將訊息組成字串,再交給 logger。
網路 API 回傳
- 在除錯模式下,
print(f"Request URL: {url}\nPayload: {json.dumps(data, indent=2)}")幫助快速定位問題。
- 在除錯模式下,
自動化測試
- 測試失敗時,用
print(f"預期: {expected}, 實際: {actual}")提供清楚的斷言資訊。
- 測試失敗時,用
總結
print() 是 Python 中最基礎也是最常用的輸出函式,而字串格式化則是讓輸出「有意義」的關鍵。
- f‑string 以其簡潔、效能與表達式支援,成為現代 Python 的首選。
str.format()提供更彈性的佈局與重複使用機制,適合需要動態組合多段文字的情境。- 舊式
%仍在遺留程式碼中常見,了解其語法有助於維護與逐步遷移。
掌握這三種格式化方式,並配合 print() 的 sep、end、file、flush 參數,我們就能寫出 易讀、易維護且效能良好 的輸出程式碼。未來在開發 CLI、日誌、報表或除錯訊息時,請依照上述最佳實踐選擇最適合的格式化手段,讓程式的「說話」更清晰、更專業。祝你寫程式順利,輸出永遠正確!