Python 例外處理 (try except)

Python 例外處理(Python Exception Handling)

這篇 Python try except 教學要解決一個老問題:猜數字遊戲裡只要輸入英文字,程式就直接當掉。例外(Exception)是程式執行中發生的錯誤,例外處理讓你「接住」這些錯誤,優雅地應對而不是整個崩潰。

try except 語法

try:
    可能出錯的程式碼
except 例外型別:
    出錯時執行的程式碼

直接看輸入防呆——前面欠的債現在還:

try:
    age = int(input("請輸入年齡:"))    # 輸入 abc
    print(f"你 {age} 歲")
except ValueError:
    print("請輸入數字,不要輸入文字")

執行範例:

請輸入年齡:abc
請輸入數字,不要輸入文字

程式不再噴出紅字錯誤,而是給出友善訊息。

常見例外型別

捕捉時指定明確的例外型別,前面文章踩過的坑都在這裡:

例外發生時機哪篇踩過
ValueError型別轉換失敗,如 int("abc")第 7 篇
TypeError型別不符的運算,如 "a" + 1第 6 篇
IndexError索引超出範圍第 11 篇
KeyError字典 key 不存在第 14 篇
ZeroDivisionError除以零第 5 篇
FileNotFoundError檔案不存在第 32 篇會遇到

多種例外可以分開接,各自處理:

data = {"score": "98"}

try:
    value = int(data["scor"])      # key 打錯了
except KeyError as e:
    print(f"找不到欄位:{e}")
except ValueError:
    print("欄位的值不是數字")

執行輸出:

找不到欄位:'scor'

as e 可以拿到例外物件,印出細節對除錯很有幫助。

else 與 finally

完整的結構有四個區塊:

try:
    num = int("100")
except ValueError:
    print("轉換失敗")
else:
    print(f"轉換成功:{num}")     # 沒發生例外才執行
finally:
    print("無論如何都會執行")     # 常用於收尾(關檔案、關連線)

執行輸出:

轉換成功:100
無論如何都會執行

實戰:問到對為止的輸入函式

把 try except 和 while 結合,做出「輸入錯就重問」的標準寫法:

def ask_int(prompt):
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print("請輸入整數!")

age = ask_int("請輸入年齡:")    # 依序輸入 abc、25
print(f"你 {age} 歲")

執行範例:

請輸入年齡:abc
請輸入整數!
請輸入年齡:25
你 25 歲

把這個函式裝回猜數字遊戲,防呆就完成了。

raise:主動拋出例外

發現不合理的狀況時,可以自己拋例外通知呼叫端:

def set_age(age):
    if age < 0:
        raise ValueError("年齡不能是負數")
    return age

try:
    set_age(-5)
except ValueError as e:
    print(f"錯誤:{e}")

執行輸出:

錯誤:年齡不能是負數

常見錯誤

1. 裸 except 接走所有錯誤

except: 連打錯字的 NameError、Ctrl+C 中斷都吞掉,bug 被藏起來更難找。永遠指定例外型別,最寬也只用 except Exception:

2. try 包得太大

整段程式都塞進 try,出錯時分不清是哪行的問題。try 區塊只包「真正可能出錯的那幾行」。

3. 用例外處理掩蓋邏輯問題

能用 if 預防的就先預防(如除數先檢查不為 0),例外處理是「真的無法預期」時的保險,不是逃避寫判斷的捷徑。

總結

try except 接住錯誤、指定明確型別、as e 取得細節;else 是沒出錯才跑、finally 是一定跑;raise 主動拋錯。標準應用「while + try」的輸入防呆函式值得背起來。下一篇把系列中出現過的錯誤訊息做一次總整理。

延伸閱讀