第18天:例外處理進階
課程簡介
在程式開發中,錯誤和異常是不可避免的。透過例外處理,我們可以在程式出現問題時給出適當的回應,並保持程式的穩定運行。今天,我們將學習例外處理的進階技巧,探索如何自定義例外、使用 else
和 finally
關鍵字,以及如何處理多重例外。這些技巧將幫助我們建立更強壯、更易於維護的程式。
學習內容
1. 多個 except
區塊
在程式中,我們可以使用多個 except
區塊來處理不同的例外類型。這樣可以針對不同的錯誤類型進行特定的處理。
範例:
1
2
3
4
5
6
7
try:
num = int(input("Enter a number: "))
result = 10 / num
except ValueError:
print("請輸入一個數字!")
except ZeroDivisionError:
print("不能除以零!")
在這個範例中,我們分別處理了 ValueError
(當輸入不是數字時)和 ZeroDivisionError
(當除以零時)的情況。
2. else
子句
else
子句可以與 try
區塊一起使用,當 try
區塊沒有拋出例外時,else
區塊中的程式碼將會被執行。
範例:
1
2
3
4
5
6
try:
num = int(input("Enter a number: "))
except ValueError:
print("請輸入一個數字!")
else:
print(f"輸入的數字是 {num}")
如果使用者輸入了一個有效的數字,則 else
區塊中的程式碼將會執行。
3. finally
子句
無論是否發生例外,finally
區塊中的程式碼都會被執行,這在需要進行資源釋放(例如關閉檔案、釋放記憶體等)的情況下特別有用。
範例:
1
2
3
4
5
6
7
8
try:
file = open("data.txt", "r")
data = file.read()
except FileNotFoundError:
print("找不到檔案!")
finally:
file.close() # NameError: name 'file' is not defined
print("檔案已關閉。")
在這裡,即使檔案找不到,finally
區塊中的 file.close()
仍然會執行。
4. 自定義例外
Python 允許開發者定義自己的例外類別,這有助於在特定情況下拋出更加有意義的錯誤。自定義例外需要繼承自內建的 Exception
類別。
範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class NegativeNumberError(Exception):
def __init__(self, value):
self.value = value
super().__init__(f"不允許負數: {self.value}")
def check_positive(num):
if num < 0:
raise NegativeNumberError(num)
try:
num = int(input("Enter a positive number: "))
check_positive(num)
except NegativeNumberError as e:
print(e)
在這個範例中,NegativeNumberError
是一個自定義的例外類別,當輸入負數時,會拋出這個例外並顯示相應的訊息。
5. 捕獲所有例外
有時,我們可能需要捕獲所有可能發生的例外。這可以通過捕獲 Exception
類別來實現,但這種方法應謹慎使用,因為它可能掩蓋程式中的真實錯誤。
範例:
1
2
3
4
try:
result = 10 / int(input("Enter a number: "))
except Exception as e:
print(f"發生錯誤: {e}")
這裡,無論是什麼類型的錯誤,都會被捕獲並輸出錯誤訊息。
6. 多重例外處理
當我們需要在同一個 except
區塊中捕獲多個例外時,可以將它們放在一個元組中來處理。
範例:
1
2
3
4
5
try:
num = int(input("Enter a number: "))
result = 10 / num
except (ValueError, ZeroDivisionError) as e:
print(f"發生錯誤: {e}")
在這個範例中,ValueError
和 ZeroDivisionError
都會被捕獲並由相同的 except
區塊處理。
教學重點
- 多個
except
區塊:學會根據不同的例外類型進行不同的處理。 else
子句:理解如何在例外沒有發生時,使用else
來執行特定的程式碼。finally
子句:掌握如何使用finally
來確保資源釋放或執行必須的清理工作。- 自定義例外:學習如何定義和拋出自定義例外,來處理特定的錯誤情況。
- 捕獲所有例外:理解如何捕獲所有例外,但應謹慎使用。
- 多重例外處理:學會如何在一個
except
區塊中處理多種例外。
任務
- 創建一個函數
divide(a, b)
,要求輸入兩個數字,並處理ZeroDivisionError
和ValueError
兩種例外。 - 定義一個自定義例外類別
InvalidAgeError
,當輸入的年齡小於 0 或大於 120 時,拋出這個例外並顯示適當的錯誤訊息。 - 使用
finally
子句來實現一個檔案讀取操作,即使檔案操作出錯,也能確保檔案被正確關閉。 - 寫一個程式,要求使用者輸入一個正整數,若輸入的數字不是正整數或發生其他錯誤,使用
Exception
捕獲並顯示相應的錯誤訊息。