相信大家學到這邊一定有碰過各式大大小小的程式錯誤,遇到程式出錯很緊張怎麼辦TAT。這裡會衍生到時候我們將程式碼上線,即時做過很多次的測試,還是有可能遇到非預期的錯誤。為了避免上線後的程式出錯導致程式停止在非預期的地方,如何捕捉異常和異常處理是本節的重點!!
大致可以將錯誤分類成三種:
發生了 ZeroDivisionError
def division(n1, n2):
return n1/n2
division(1, 0)
通常應該會做一些輸入資料的檢查來避免這種錯誤,但假設在爬網站,可能有各式各樣的錯誤會發生。今天發現一個錯誤就要改一次程式碼,明天發現錯誤又要改,那這支程式可能永遠難以上線。為了避免這樣的窘境,我們可以加上例外處理,讓程式去捕捉我們沒有想過的異常。另外也可以思考一個情境是提供程式給使用者,使用者可能會輸入你沒有想過的情境。如果因為他的輸入導致你的程式異常,那使用者體驗可能會很差。
def division(n1, n2):
try:
return n1/n2
except ZeroDivisionError:
print("除數不可以為0")
division(1, 0)
>>> 除數不可以為0
有個調皮鬼輸入文字,那怎麼辦?
又發生錯誤了QQ
division('1', '0')
因此寫 try except 想到的盡量加上去,最後再用 Exception 撿剩下的錯誤。
def division(n1, n2):
try:
return n1/n2
except ZeroDivisionError:
print("除數不可以為0")
except TypeError:
print("請輸入數字")
except Exception as e
print("錯誤資訊:", e)
division('1', '0')
>>> 請輸入數字
剛剛上面介紹還並非完全型態呢XD
來來來這裡是完全型態
try:
# 嘗試執行的程式碼
except:
# 當程式出現異常時執行的程式碼
else:
# 錯誤沒有發生就會執行的程式碼
finally:
# 無論如何都要執行的程式碼
def read_txt(file_path):
try:
with open(file_path) as file:
data = file.read()
except FileNotFoundError:
print("路徑異常:", file_path)
else:
print("成功了!")
finally:
print("感謝您使用本程式!")
以下是常見的例外錯誤,大家可以自行參考,最後一個 Exception 代表通用型。
Type | Name |
---|---|
Attribute | 沒有這個屬性 |
FileNotFoundError | 找不到檔案 |
IOError | 輸入輸出的錯誤 |
IndexError | 索引超出範圍 |
KeyError | 沒有該鍵 |
MemoryError | 記憶體超出範圍 |
NameError | 未宣告該變數 |
SyntaxError | 語法錯誤 |
SystemError | 系統錯誤 |
TypeError | 資料類別錯誤 |
ValueError | 傳入無效參數 |
ZeroDivisionError | 除數為 0 |
Exception | 可以代替錯誤的關鍵字 |
有時候是我們想要檢驗邏輯是否錯誤,如果錯誤,就請程式停止不要再繼續執行
此時該怎麼做呢? 可以使用 raise 關鍵字
def input_phone(number: str):
if len(number) != 10:
raise Exception('您的手機號碼長度不正確')
print('DONE')
input_phone('0912345678')
>>> DONE
input_phone('09123456789')
若想要自己寫例外的話,我們必須繼承 Exception 物件。
若想讓定義的物件像一般常見到的例外物件一樣,能夠直接透過物件實體來輸出的話,須在物件中加入 __str__ 的物件方法。
class PasswordInputError(Exception):
def __init__(self, password):
self.password = password
def __str__(self):
return '錯誤訊息:' + self.password
print(e) 會調用 __str__ 的魔法方法,重寫 Exception 原本寫的方法。
password = input("請設定密碼")
try:
if len(password) < 5:
raise PasswordInputError(password)
except Exception as e:
print(e)
assert 是 raise 的一種特殊形式
assert 運算式, 參數
如果運算式是 False,並且內建的 __debug__為 True,則引發帶有參數的 AssertError。
通常用於檢查異常、寫測試案例等等
save_money = input('請輸入存款金額')
assert int(save_money) > 0 , '請輸入大於零的數字'