首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python str.expandtabs() 完整教學:製表符展開與對齊技巧

     編輯:更多程式設計知識

在處理表格輸出、日誌格式化、程式碼產生等場景時,常需將字串中的製表符(\t)轉換為固定寬度的空格以達成對齊。Python 內建 str.expandtabs() 方法專為此設計,支援自訂 tab 寬度,本文完整解析其行為、參數與實戰技巧。

方法簽名


str.expandtabs(tabsize=8) -> str
  • tabsize:每個 tab 停靠位的字元寬度,預設 8。必須為非負整數。
  • 回傳:新字串,所有 \t 替換為適量空格,使下一字元落在下一個 tab stop(tabsize 的倍數位置)。

核心規則:Tab Stop 計算

tab stop 位置為 0, tabsize, 2*tabsize, 3*tabsize, ...。遇到 \t 時,補齊空格直到下一個 stop。


# tabsize=8 (預設)
"a\tb"      -> "a       b"      # a 在 0,下一 stop 8,補 7 空格
"abc\tde"   -> "abc     de"     # abc 佔 0-2,下一 stop 8,補 5 空格
"12345678\tX" -> "12345678 X"   # 已在 stop 8,補 1 空格到 stop 16

基本範例


s = "Name\tAge\tCity"
print("預設(8):", repr(s.expandtabs()))
# 'Name    Age     City'

print("tabsize=4:", repr(s.expandtabs(4)))
# 'Name Age City'

print("tabsize=12:", repr(s.expandtabs(12)))
# 'Name        Age        City'

進階:產生對齊表格


data = [
    ("Alice", "30", "Taipei"),
    ("Bob", "25", "Tokyo"),
    ("Charlie", "35", "New York")
]

# 計算每欄最大寬度(含標頭)
headers = ("Name", "Age", "City")
col_widths = [max(len(str(row[i])) for row in [headers] + data) for i in range(3)]

# 產生格式化字串:用 \t 分隔,再 expandtabs 到最大寬度+2
# 注意:expandtabs 是「跳到下一 stop」,非固定寬度,需配合計算
def format_row(row, widths):
    parts = []
    for i, val in enumerate(row):
        val = str(val)
        # 手動左對齊填充到指定寬度,再加 \t 讓 expandtabs 只補 1 空格
        parts.append(val.ljust(widths[i]) + "\t")
    return "".join(parts).expandtabs(1)  # tabsize=1 相當於不再展開,只保留手動填充

for row in [headers] + data:
    print(format_row(row, col_widths))

輸出:

Name     Age City
Alice    30  Taipei
Bob      25  Tokyo
Charlie  35  New York

比較:expandtabs vs str.format vs f-string

方法適用場景優點缺點
expandtabs舊代碼遷移、簡單 tab 分隔資料一行搞定、無需計算寬度難以精確控制每欄寬度、中文字元寬度不等
str.format / f-string現代代碼、精確對齊、中文支援完全控制、支援對齊/填充/精度需預先知道寬度
textwrap / tabulate複雜表格、自動換行、邊框功能豐富、專業輸出需額外依賴

中文字元寬度陷阱

expandtabs 按**字元數**計算寬度,但中文字元在終端機通常佔 2 格寬度(East Asian Width)。直接使用會導致對齊錯位:


s = "姓名\t年齡\t城市"
print(s.expandtabs(8))
# 輸出視覺上會錯位,因 "姓名" 2 字元但佔 4 格寬

解決方案:使用 wcwidth 套件計算顯示寬度,或改用 tabulate / rich 等支援 CJK 的庫。

常見用法總結

  • s.expandtabs():預設 8 字元,快速檢視 tab 分隔資料。
  • s.expandtabs(4):程式碼縮排轉空格(PEP 8 建議 4 空格)。
  • s.expandtabs(0):移除所有 tab(替換為空字串)。
  • '\t'.join(fields).expandtabs(width):快速產生粗略對齊表格。

一鍵轉換腳本:將檔案中所有 tab 轉為 4 空格


import sys, os

def convert_file(path, tabsize=4, backup=True):
    if backup:
        os.rename(path, path + ".bak")
    with open(path + ".bak", 'r', encoding='utf-8') as f:
        content = f.read()
    with open(path, 'w', encoding='utf-8') as f:
        f.write(content.expandtabs(tabsize))
    print(f"Converted: {path}")

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python tab2space.py file1.py [file2.py ...]")
        sys.exit(1)
    for f in sys.argv[1:]:
        convert_file(f)

掌握 expandtabs() 的 tab stop 機制與限制,能在快速原型、舊代碼整理、簡單表格輸出場合發揮最大效用;正式報表建議改用 f-string 或專業表格庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved