在 Python 中建立自定義異常
本教程將演示你可以在 Python 中建立自定義異常類。在這裡,我們將展示如何正確執行異常處理、定義自定義異常類以及覆蓋現有的內建異常。
異常是一種事件,每當程式中的某些內容未按預期執行或中斷程式預期用例的流程時就會發生。如果沒有異常處理,程式將完全停止執行,並且必須修復或處理異常。
在 Python 中建立自定義異常類
在 Python 中建立異常類的方式與建立常規類的方式相同。主要區別在於你必須包含 Python 的基類 Exception
以通知編譯器你正在建立的類是異常類。
讓我們測試這個方法以建立一個名為 DemoException
的異常類,並在內部使用佔位符控制流關鍵字 pass
作為佔位符。
class DemoException(Exception):
pass
在 Python 中使用關鍵字 raise
執行異常引發
要測試 DemoException
類並檢視它在實際觸發時顯示的內容,請執行異常引發。異常引發與其他程式語言中的異常丟擲同義。
使用關鍵字 raise
,使用給定的異常類觸發異常並輸出異常訊息。
class DemoException(Exception):
pass
raise DemoException
輸出:
Traceback (most recent call last):
File "/Users/demo/python/demo_exception.py", line 4, in <module>
raise DemoException
__main__.DemoException
如果未宣告自定義異常訊息,則終端中將顯示標準異常。
在 Python 中宣告自定義異常訊息
要為 DemoException
宣告自定義異常訊息,請覆蓋異常類的 __init__()
方法,並在引數中包含應為異常輸出的訊息,以及強制自引用引數 self
。
例如,讓我們覆蓋 __init__()
方法併為 DemoException
類建立自定義訊息:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
請注意,要成功地將訊息整合到你的異常中,請呼叫基本 Exception
類、__init__()
方法,並將 message
作為引數包含在內。
讓我們再次使用 raise
關鍵字呼叫異常類,現在,使用它傳遞自定義訊息:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
message = "Exception Triggered! Something went wrong."
raise DemoException(message)
輸出應如下所示:
Traceback (most recent call last):
File "/Users/demo/python/helloworld.py", line 6, in <module>
raise DemoException(message)
__main__.DemoException: Exception Triggered! Something went wrong.
我們現在已經成功建立並觸發了一個帶有自定義錯誤訊息的異常類。
對於可能觸發異常的實際情況,我們如何處理和引發這些異常?你可以通過使用 try...except
塊實現異常處理來巧妙地解決這個問題。
使用 Python 中的 try...except
塊執行異常處理
try...except
塊很像 Java 等其他語言中的 try-catch
塊。
try...except
塊有 2 個主要塊和 2 個可選塊:
try
(必需)- 負責封裝可能觸發異常的程式碼塊的主塊。每當觸發異常時,try
塊就會停止其中的整個過程。except
(必需)- 每當觸發指定的異常時,塊程式就會繼續進行。此塊通常包含呼叫者的描述性錯誤訊息或只是一個簡單的print()
語句。在一個try
塊中可能有多個except
塊,每個塊都捕獲不同的異常。else
(可選) - 如果try
塊沒有觸發任何異常,這個可選塊是程式將繼續的地方。finally
(可選)- 無論是否觸發異常,此可選塊都會在前 3 個塊中的所有內容都執行完畢後執行。
讓我們使用前面使用 DemoException
類的示例來嘗試一個簡單的 try...except
塊。
首先,將 raise
關鍵字包裝在一個函式中,並將其放入 try...except
塊中。
我們將為此示例建立的函式是一個函式,它接受一個數字並在它傳送 0
時丟擲異常。如果它傳送任何其他號碼,則程式碼將按預期進行。參考下面的例子:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
message = "Exception Triggered! Something went wrong."
def triggerException(num):
if (num == 0):
raise DemoException(message)
else:
print(num)
try:
triggerException(0)
print("Code has successfully been executed.")
except DemoException:
print("Error: Number should not be 0.")
由於 triggerException()
將 0
作為引數傳遞,程式碼應該觸發 DemoException
。在這裡,我們應該期望 raise
關鍵字訊息被 except
塊內的任何內容作為輸出覆蓋。
請注意,未輸出 triggerException()
函式呼叫後的 print()
行。這是因為函式引發了異常;因此,它立即停止了 try
塊中的所有程序,並直接進入 except
塊。
輸出:
Error: Number should not be 0.
現在,讓我們嘗試傳遞一個有效的數字,例如 20
。
try:
triggerException(20)
print("Code has successfully been executed.")
except DemoException:
print("Error: Number should not be 0.")
輸出:
20
Code has successfully been executed.
讓我們嘗試連結 except
塊並建立另一個異常。讓我們呼叫新的異常 NumberFormatException
,如果給定的輸入不是數字就會觸發。對於這個異常類,讓我們在類中宣告訊息。
class NumberFormatException(Exception, value):
message = f'{value} is not a number'
def __init__(self):
super().__init__(message)
現在,修改上面的程式碼來處理新的異常類 NumberFormatException
:
class DemoException(Exception):
def __init__(self, message):
super().__init__(message)
class NumberFormatException(Exception):
def __init__(self, message, value):
message = f'{value} is not a number'
super().__init__(message)
message = "Exception occured."
def triggerException(num):
if (not num.isdigit()):
raise NumberFormatException(message, num)
elif (num == 0):
raise DemoException(message)
else:
print(num)
num = "sample string"
try:
triggerException(num)
print("Code has successfully been executed.")
except DemoException:
print("Error: Number should not be 0.")
except NumberFormatException:
print(num+" is not a number.")
在這段程式碼中,傳遞給 triggerException()
的 num
的值是一個字串'sample string'
,因此應該觸發 NumberFormatException
。
輸出:
sample string is not a number.
總之,在 Python 中建立自定義異常就像建立一個新類一樣簡單,但在類定義中將 Exception
類作為一個額外的引數。raise
關鍵字用於觸發給定異常類的異常。try...except
塊用於將一個或多個異常包裝在一個程式碼塊中,並在處理該異常時修改程式碼的作用,而不僅僅是完全關閉程式。
Skilled in Python, Java, Spring Boot, AngularJS, and Agile Methodologies. Strong engineering professional with a passion for development and always seeking opportunities for personal and career growth. A Technical Writer writing about comprehensive how-to articles, environment set-ups, and technical walkthroughs. Specializes in writing Python, Java, Spring, and SQL articles.
LinkedIn