目標:
- 掌握例外處理的基本概念和語法。
- 理解 Python 中常見的例外類型。
- 學習如何設計更高效的例外處理邏輯。
- 理解例外處理的進階應用(如自訂例外)。
一、什麼是例外處理?
定義:
- 程式執行中,可能遇到 錯誤 或 非預期事件(例如:檔案不存在、除以零)。
- 例外處理讓程式能在遇到錯誤時,有計劃地進行 錯誤處理,而非直接崩潰。
為什麼需要例外處理?
- 提高程式穩定性。
- 提供更友好的錯誤訊息。
- 允許程式在錯誤後繼續執行。
範例:基本例外處理
python
try:
x = 10 / 0 # 會引發 ZeroDivisionError
except ZeroDivisionError:
print("Cannot divide by zero.")
二、例外處理的基本語法
語法結構:
python
try:
# 可能引發錯誤的程式碼
except <ExceptionType>:
# 錯誤處理邏輯
else:
# 如果沒有發生錯誤,執行此區塊
finally:
# 無論是否發生錯誤,都執行此區塊
語法解析:
try
:包含可能引發錯誤的程式碼。except
:捕捉特定的錯誤並處理。else
:try
區塊無錯誤時執行。finally
:必定執行,用於清理資源(如關閉文件)。
三、例外處理的應用與進階
1. 捕捉多個例外
- 可以使用多個
except
,針對不同例外執行不同邏輯:
python
try:
lst = [1, 2, 3]
print(lst[10]) # 會引發 IndexError
except IndexError:
print("Index out of range.")
except KeyError:
print("Key not found.")
2. 常見例外類型
以下是常見例外類型,透過範例加深理解:
例外類型 | 範例 | 解釋 |
---|---|---|
TypeError | print("a" ** 2) |
不匹配的資料型態操作 |
NameError | print(undeclared_variable) |
使用未定義變數 |
IndexError | lst = [1]; print(lst[10]) |
索引超出範圍 |
KeyError | d = {"a": 1}; print(d["b"]) |
字典鍵不存在 |
ValueError | int("abc") |
無法轉換的數值 |
FileNotFoundError | open("nonexistent.txt") |
檔案不存在 |
RecursionError | 遞迴函式無終止條件,導致堆疊溢位(stack overflow) |
3. 使用 else
和 finally
else
:try
區塊沒有錯誤時執行。finally
:無論有無錯誤,最後執行。
範例:
python
try:
result = 10 / 2
except ZeroDivisionError:
print("Cannot divide by zero.")
else:
print("Calculation successful:", result)
finally:
print("End of calculation.")
4. 例外處理的順序
例外處理的順序至關重要,必須先捕捉子類型例外,再捕捉父類型例外:
python
try:
lst = [1, 2, 3]
print(lst[4]) # IndexError
except LookupError:
print("This is a lookup error.") # 父類型
except IndexError:
print("This is an index error.") # 子類型,永遠不會被執行
四、例外處理策略:LBYL vs EAFP
LBYL (Look Before You Leap):
- 先檢查後執行,適用於需要預測錯誤的場景。
- 範例:
python
def safe_divide(x, y):
if y == 0:
print("Cannot divide by zero.")
return None
return x / y
EAFP (Easier to Ask Forgiveness than Permission):
- 先執行後處理,適用於簡化程式碼的場景。
- 範例:
python
def safe_divide(x, y):
try:
return x / y
except ZeroDivisionError:
print("Cannot divide by zero.")
return None
五、進階應用:自訂例外
1. 自訂例外類型
- 自訂例外類型可用於特定業務邏輯。
python
class NegativeNumberException(RuntimeError):
def __init__(self, number):
super().__init__(f"Negative number detected: {number}")
2. 與業務邏輯結合
- 範例:
python
def check_number(number):
if number < 0:
raise NegativeNumberException(number)
print("Valid number:", number)
try:
check_number(-5)
except NegativeNumberException as e:
print(e)
六、課堂練習
基礎練習:
- 寫一個函式,判斷輸入是否為整數,若否則提示用戶重新輸入。
python
def ask_for_int():
while True:
try:
num = int(input("Enter an integer: "))
print(f"You entered: {num}")
break
except ValueError:
print("This is not an integer. Please try again.")
ask_for_int()
進階練習:
- 自訂例外,處理輸入負數的情況,並計算輸入數值的平方。
挑戰題:
- 設計一個成績管理系統,若輸入的成績超過範圍,則引發例外,並提示重新輸入。