我們常常在撰寫程式碼的時候,常常會因為程式碼編寫錯誤或者是呼叫對象不存在導致程式被中斷而直譯器就會給出一堆異常訊息(Exception),這時候我們可以從直譯器給出的Exception了解程式碼哪裡出錯進而修改程式碼。但是,當程式越寫越大的時候,除錯就不容易了,甚至要找到錯誤發生在哪一行程式都要找很久,這時候對於Exception的處理就非常重要了,有助於我們可以很快知道發生錯誤的程式在哪一個區段並也知道發生哪一類的異常,以利我們可以很快修改程式碼。當然,要學會如何處理Exception,要先知道常見的Exception類性,我們將常見的Exception類型整理如下並給出簡單的程式碼範例:
12.1 Exception處理的基本語法
語法1
try:
可能引發Exception的程式區塊
except:
Exception發生時執行的區塊
以下我們給一個範例:
我們可以從上述的範例可以看出,我們們設計了一個除法函數div(a,b),這個函數在執行div(1,2)的時候沒有問題,但執行div(1,0)時候就會發生異常,此時程式就會進入except區塊執行print(“除法發生異常!”)。值得特別注意的是,整個程式執行完沒有出現任何異常訊息而且也沒有中斷,這個是使用try-except的好處,但上述範例雖然沒有出現任何異常訊息,所以我們只知道發生異常,但不知道發生甚麼類型的異常,所以我們可以採用第二種寫法,寫法如下:
語法2
try:
可能引發Exception的程式區塊
except 例外類型 as 參數:
Exception發生時執行的區塊
其中例外類型可以是一開始的表格中所列的其中之一,但通常我們都會使用Exception,因為它可以代表所有的異常錯誤。後面的參數則可以傳遞錯誤的資訊。以下我們給出一個範例如下:
語法3
try:
可能引發Exception的程式區塊
except 例外類型 as 參數:
Exception發生時執行的區塊
finally:
一定會執行的程式區塊
finally 的部分會在try…except執行完後執行,一般都是用來刪除物件或關閉檔案。
語法4
try:
可能引發Exception的程式區塊
except 例外類型 as 參數:
Exception發生時執行的區塊
else:
try程式區塊執行無發生異常時會執行的程式區塊
finally:
一定會執行的程式區塊
else 區塊是當try程式區塊執行無發生異常時會執行的程式區塊,也就是說發生異常時,else區塊不會執行,與finally區塊不同,finally區塊則無論有無發生異常一定都會執行。
語法5
try:
可能引發Exception的程式區塊
except (例外類型1, 例外類型2,…) as 參數:
Exception發生時執行的區塊
expect 部分可以一次寫多個例外類型,則當異常發生時。參數會針對對應的異常類型給出異常訊息,但如發生的異常的類型不在所設定的例外類型中,則程式會中斷並拋出異常訊息。如下範例:
12.2 自訂例外類型
我們可以利用raise語句拋出例外訊息,即使程式語法正確。請看以下範例:
這個做法可以之後在我們撰寫程式時,在滿足某些條件下(程式語言是合法的),主動拋出例外訊息。我們甚至可以自行定義例外類別,並使用它拋出異常訊息,但我們要自訂自己的例外類別,我們可以利用繼承Exception類別來建立。
12.3紀錄例外發生過程
我們可以將程式發生的例外用except逮獲並拋出異常訊息,但異常訊息的拋出是在出現在Console區塊。而且當成是執行多次,過程中發生的異常並不會被逐一記錄下來,只會有最後一次的異常訊息,所以我們如果希望程式執行過程中所發生的異常訊息被記錄下來,我們可以將異常訊息以”不清除現有內容的方式”寫入文字檔,以達到異常訊息的紀錄。
我們也可以用traceback模組中的format_exc()方法將異常訊息記錄在文字檔中。
我們可以發現兩個方法的差異,第一個方法只會紀錄expect所拋出的異常訊息,而traceback模組中的format.exc()方法則可以拋出更完整的異常訊息,例如文件名稱、發生異常的行數、異常種類、異常訊息等。
12.4 assert斷言
assert主要用於程式開發中,在特定條件下拋出異常訊息(不需要用raise與try…except),可以讓程式設計師很快知道程式問題出在哪裡,但此方式會中斷程式與try…except不同。
語法:
assert
判斷式,自訂異常訊息
留言
張貼留言