字串編碼是文字資料儲存、傳輸、跨系統交換的核心環節。Python 3 字串為 Unicode,encode() 將字串轉為 bytes 位元組序列,支援數百種編碼標準。本文詳細說明語法、常用編碼、錯誤處理機制、Base64 應用、效能與最佳實務。
str.encode(encoding='utf-8', errors='strict')
'utf-8'。'strict'(拋出例外)。bytes 物件(不可變位元組序列)。| 編碼 | 別名 | 特性 | 適用場景 |
|---|---|---|---|
| utf-8 | utf8 | 變長 1-4 bytes、ASCII 相容、Unicode 完整支援 | Web、API、檔案、資料庫(首選) |
| utf-16 | utf16 | 固定 2/4 bytes、含 BOM、Windows 內部常用 | Windows API、某些舊系統 |
| utf-32 | utf32 | 固定 4 bytes、直接對應 code point | 內部處理、學術研究 |
| ascii | us-ascii | 僅 0-127、無法表示中文 | 舊系統相容、純英文 |
| big5 | big5-tw | 繁體中文常用、雙位元組 | 台灣舊系統、政府資料 |
| gbk | gb2312, cp936 | 簡體中文常用、雙位元組 | 中國大陸舊系統 |
| latin-1 | iso-8859-1 | 單位元組 0-255、西歐語系 | 舊網頁、某些協議 |
| cp950 | ms950 | Windows 繁中代碼頁 | Windows 中文環境 |
s = "Hello 世界 😀"
# 1. strict(預設):遇無法編碼字元拋出 UnicodeEncodeError
try:
s.encode('ascii')
except UnicodeEncodeError as e:
print(f"Strict error: {e}")
# 2. ignore:直接跳過無法編碼字元
print(s.encode('ascii', 'ignore')) # b'Hello '
# 3. replace:用 ? 取代(或編碼特定取代字元)
print(s.encode('ascii', 'replace')) # b'Hello ?? ??'
# 4. xmlcharrefreplace:用 XML 數字實體取代
print(s.encode('ascii', 'xmlcharrefreplace'))
# b'Hello 世界 😀'
# 5. backslashreplace:用 \x/\u/\U 轉義序列取代
print(s.encode('ascii', 'backslashreplace'))
# b'Hello \\u4e16\\u754c \\U0001f600'
# 6. namereplace:用 \N{name} 取代(Python 3.5+)
print(s.encode('ascii', 'namereplace'))
# b'Hello \\N{CJK UNIFIED IDEOGRAPH-4E16}...'
import base64
# 字串 → bytes → Base64 bytes → Base64 字串
text = "Hello World"
b64_bytes = base64.b64encode(text.encode('utf-8'))
b64_str = b64_bytes.decode('ascii')
print(b64_str) # SGVsbG8gV29ybGQ=
# 解碼
decoded = base64.b64decode(b64_str).decode('utf-8')
print(decoded) # Hello World
# URL 安全 Base64(無 + / =)
url_safe = base64.urlsafe_b64encode(text.encode()).decode()
print(url_safe) # SGVsbG8gV29ybGQ=
content = "中文內容\nEnglish\n😀"
# 寫入 UTF-8(預設)
with open('utf8.txt', 'w', encoding='utf-8') as f:
f.write(content)
# 寫入 Big5(舊系統相容)
with open('big5.txt', 'w', encoding='big5', errors='replace') as f:
f.write(content)
# 二進位模式寫入 bytes
with open('raw.bin', 'wb') as f:
f.write(content.encode('utf-8'))
import urllib.request
import json
data = {"message": "Hello 世界"}
json_bytes = json.dumps(data, ensure_ascii=False).encode('utf-8')
req = urllib.request.Request(
'https://httpbin.org/post',
data=json_bytes,
headers={'Content-Type': 'application/json; charset=utf-8'}
)
with urllib.request.urlopen(req) as resp:
print(resp.read().decode())
# MySQL (pymysql)
import pymysql
conn = pymysql.connect(
host='localhost',
user='root',
password='pass',
database='test',
charset='utf8mb4' # 完整 Unicode 支援(含 Emoji)
)
# PostgreSQL (psycopg2)
import psycopg2
conn = psycopg2.connect(
host='localhost',
database='test',
user='postgres',
password='pass',
client_encoding='utf8'
)
import hashlib
import hmac
message = "secret message"
key = b"secret-key"
# HMAC 需 bytes
sig = hmac.new(key, message.encode('utf-8'), hashlib.sha256).hexdigest()
print(sig)
# 密碼雜湊
pwd_hash = hashlib.pbkdf2_hmac('sha256',
b"password123", b"salt", 100000).hex()
def encode_stream(input_file, output_file, encoding='utf-8', chunk_size=8192):
with open(input_file, 'r', encoding=encoding) as fin, \
open(output_file, 'wb') as fout:
while True:
chunk = fin.read(chunk_size)
if not chunk:
break
fout.write(chunk.encode(encoding))
bytes 結果。
# 錯誤
"hello".encode('utf-8').encode('utf-8') # AttributeError: 'bytes' has no attribute 'encode'
# 正確
"hello".encode('utf-8') # bytes
b"hello".decode('utf-8') # str
json.dumps 預設輸出 ASCII 轉義,中文需關閉。`json.dumps(obj, ensure_ascii=False).encode('utf-8')`encode() 是 Unicode 字串轉位元組序列的標準方法,**預設 UTF-8、支援完整錯誤處理策略**。關鍵掌握:編碼選擇(UTF-8 首選)、錯誤策略(strict/replace/ignore)、Base64 應用、檔案/網路/資料庫編碼一致性。**永遠顯式指定 encoding**,避免跨平台、跨系統亂碼。搭配 decode() 形成完整編解碼循環。