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」的輸入防呆函式值得背起來。下一篇把系列中出現過的錯誤訊息做一次總整理。