「項目標題長得像『第 3 項』,正規表達式撈出數字轉成 int 就好了。」
這句話在資料乾淨的時候完全成立。但只要來源站的資料量夠大、時間夠久,遲早會出現不遵守慣例的標題——可能是合輯、番外篇、或者一個帶小數點的編號。如果程式碼寫死「一定拿得到整數」,遇到這種例外就是直接拋未處理的例外,整批處理中斷在那一項。
❌ 反例:直接轉型,例外情境直接讓整批處理中斷
def parse_index(title: str) -> int:
matched = re.search(r'第([\w.]+)項', title)
return int(matched.group(1)) # 遇到非數字就整個中斷
✅ 正例:轉型失敗時有明確的退路,不影響其他項目繼續處理
def parse_index(title: str) -> Union[int, str]:
matched = re.search(r'第([\w.]+)項', title)
raw = matched.group(1) if matched else title.strip()
try:
return int(raw)
except ValueError:
return raw # 拿不到數字,保留原始文字,交給呼叫端決定怎麼處理
正例的關鍵不是「用 try/except 蓋住錯誤」,而是明確定義「拿不到數字」這個結果該長什麼樣子,讓呼叫端可以決定要跳過、記錄下來、還是用別的方式處理,而不是讓一個例外中斷整批原本可以正常處理的項目。
值得強調的是,這不是在提倡到處包 try/except 吞掉錯誤。真正的重點是先想清楚「這個情境下,失敗代表什麼、該回傳什麼」,再決定要不要攔截這個例外。如果失敗代表資料本身有嚴重問題、後續完全無法處理,讓例外往上拋、中斷流程反而是對的;但如果失敗只是「這一項比較特殊,換個方式處理就好」,那就該有一條明確的退路,而不是讓一整批資料因為一項例外而全部卡住。
你的程式碼裡有沒有「多數情況成立,但沒處理過少數例外」的轉型或解析邏輯?那段程式碼遇到例外時,是讓整個流程中斷,還是有明確的退路?
明天回頭檢視這幾天講的抽象層:這一層抽象值得嗎?三個來源站跟十個來源站,成本轉折點在哪裡。