Python 錯誤處理(Error Handling)完整教學 | Python
在撰寫 Python 程式時,錯誤是無法避免的。例外處理(Exception Handling) 讓你能優雅地處理這些錯誤,避免程式意外中斷。本篇將介紹 Python 的錯誤處理機制,從基礎的
try/except語法到自定義例外類別,幫助你寫出更穩健的程式碼。
try/except 基礎
try/except 是 Python 中最基本的錯誤處理語法。將可能出錯的程式碼放在 try 區塊中,用 except 捕捉並處理錯誤:
try:
number = int(input("請輸入一個數字:"))
result = 10 / number
print(f"結果是:{result}")
except ValueError:
print("錯誤:請輸入有效的數字")
except ZeroDivisionError:
print("錯誤:不能除以零")
捕捉例外資訊
使用 as 關鍵字可以取得例外物件,獲取更詳細的錯誤資訊:
try:
numbers = [1, 2, 3]
print(numbers[10])
except IndexError as e:
print(f"發生錯誤:{e}")
# 輸出:發生錯誤:list index out of range
你也可以用一個 except 同時捕捉多種例外:
try:
value = int("abc")
except (ValueError, TypeError) as e:
print(f"型別相關錯誤:{e}")
# 輸出:型別相關錯誤:invalid literal for int() with base 10: 'abc'
else 與 finally
else 區塊在 沒有發生例外 時執行,finally 區塊 無論是否發生例外 都會執行:
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("檔案不存在")
else:
# 只在成功讀取時執行
print(f"檔案內容:{content}")
finally:
# 無論如何都會執行,適合做清理工作
print("檔案操作結束")
完整的執行順序是:try -> 成功則 else -> finally,或 try -> 失敗則 except -> finally。
常見內建例外
Python 提供了許多內建的例外類型(Exception),以下是最常見的幾種:
# ValueError — 值不正確
int("abc") # ValueError: invalid literal for int()
# TypeError — 型別不正確
"hello" + 123 # TypeError: can only concatenate str to str
# KeyError — 字典中找不到鍵
my_dict = {"a": 1}
my_dict["b"] # KeyError: 'b'
# FileNotFoundError — 檔案不存在
open("不存在的檔案.txt") # FileNotFoundError
# IndexError — 索引超出範圍
[1, 2, 3][10] # IndexError: list index out of range
# AttributeError — 屬性不存在
"hello".append("!") # AttributeError: 'str' object has no attribute 'append'
主動拋出例外
使用 raise 關鍵字可以主動拋出例外,這在驗證輸入資料時特別有用:
def set_age(age):
if not isinstance(age, int):
raise TypeError("年齡必須是整數")
if age < 0 or age > 150:
raise ValueError("年齡必須在 0 到 150 之間")
return age
try:
set_age(-5)
except ValueError as e:
print(f"驗證失敗:{e}")
# 輸出:驗證失敗:年齡必須在 0 到 150 之間
自定義例外類別
當內建例外無法精確描述你的錯誤情境時,可以建立自定義例外類別。自定義例外應繼承自 Exception:
class InsufficientBalanceError(Exception):
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"餘額不足:目前餘額 {balance},嘗試提取 {amount}")
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientBalanceError(self.balance, amount)
self.balance -= amount
return self.balance
account = BankAccount(1000)
try:
account.withdraw(1500)
except InsufficientBalanceError as e:
print(e)
# 輸出:餘額不足:目前餘額 1000,嘗試提取 1500
EAFP vs LBYL
Python 社群推崇兩種不同的錯誤處理風格:
LBYL(Look Before You Leap) — 先檢查再行動:
# LBYL 風格
if key in my_dict:
value = my_dict[key]
else:
value = "預設值"
EAFP(Easier to Ask Forgiveness than Permission) — 先做再說,有錯再處理:
# EAFP 風格(更 Pythonic)
try:
value = my_dict[key]
except KeyError:
value = "預設值"
在 Python 中,EAFP 風格通常被認為更 Pythonic,因為它更簡潔,在大多數情況下效能也更好(因為例外很少發生)。
總結
例外處理 是撰寫穩健 Python 程式不可或缺的一環。善用 try/except/else/finally 結構來處理不同情境,了解常見的內建例外類型,並在需要時建立自定義例外類別。記住 Python 的 EAFP 風格——先行動、再處理例外,這會讓你的程式碼更簡潔、更 Pythonic。希望這篇文章能幫助你寫出更穩健的 Python 程式。
例外處理經常與函式搭配使用,建議先閱讀 Python 函數(Functions)入門指南。自定義例外類別需要用到繼承的概念,可以參考 Python 的物件導向程式設計。