跳到主要內容

Python筆記(12)-例外(Exception)處理

我們常常在撰寫程式碼的時候,常常會因為程式碼編寫錯誤或者是呼叫對象不存在導致程式被中斷而直譯器就會給出一堆異常訊息(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主要用於程式開發中,在特定條件下拋出異常訊息(不需要用raisetry…except),可以讓程式設計師很快知道程式問題出在哪裡,但此方式會中斷程式與try…except不同。

語法:

        assert 判斷式,自訂異常訊息

留言

這個網誌中的熱門文章

RPA-Uipath筆記(1) - 如何從網路上下載資料並存至指定路徑

最近在做 RPA 相關專案時遇到了這個問題: 如何從網路上下載資料並存至指定路徑? 針對這個問題我們採取的解決方案是 先讓檔案下載到電腦的預設路徑,再將檔案移動到我們指定的資料夾 。 以下我們用下載政府公開資料平台的資料 ("https://data.gov.tw/dataset/116285") 為例, Uipath 的流程建立如下: 使用到了 Wait for Download 、 Move File 、 Delete File 三個 Activity , Wait for Download 中 Monitored folder 必須放瀏覽器中設定的下載檔案的預設路徑且關閉詢問儲存位置。 Downloaded file 則是設定一個變數名稱 downloadfile( 可自訂 ) ,此變數的資料型態是 FileInfo 。中間則放入下載的流程步驟,從下載開始到結束都會在此 Activity 中執行完畢,執行完後所下載的檔案的相關資訊都會被存放在變數 downloadfile 中。 接下來是將檔案從預設下載路徑中移至指定路徑,這裡就需要下載預設路徑與指定路徑,這兩個我們在流程一開始就建了了兩個變數 dnlo_path 、 asng_path ,寫法如下: dnlo_path = "C:\Users\" +system.Environment.UserName+ "\Downloads" system.Environment.UserName à VB 語法,代表目前電腦的使用者名稱。 asng_path = "D:\Bolg 資料 \Uipath\Uipath(1)" Move File Activity 中 From 要放入目前檔案的位置; To 則要放入檔案存放的指定的位置,但因為是要做檔案的移動,所以以上兩個路徑後面都要再加上檔案名稱,這時可以使用 downloadfile 這個變數的屬性值叫出檔案名稱( downloadfile.Name ),當檔案名稱是隨機變動的時候,非常好用。另外,特別值得注意的是, To 的部分在加上檔案名稱時,可以不用用原始檔案的名稱,這時可以同時達到修改檔名的效果。 Overwrite 的部分打勾代表再重複執行一次的時...

RPA-Uipath(2) - 字串分割(String.Split())與合併(String.join())

在資料清理中,我們常常需要對字串進行分割或合併,今天來簡單介紹 Uipath 中字串如何進行分割與合併。 1.      字串分隔 ( 單一分割符號 ) 我們首先建了一個字串變數 Str1= "Jimmy,Johnson,Shawn,Alan,Nick" ,我們現在想把這些人名一個一個切割出來,很明顯只要將 ”,” 作為分個符號就可以了。這邊我們建立一個陣列變數 Str1_Array=Str1.split(","c) ,這個陣列變數就會儲存分割出來的結果。我們接下來用 For each 與 Write Line 將陣列的每一項內容印出來,就可以知道我們分割的結果有沒有成功。 2.      字串分隔 ( 多個分割符號 ) 我們首先建了一個字串變數 Str2= "Jimmy,Johnson.Shawn Alan,Nick" ,我們現在想把這些人名一個一個切割出來,很明顯要將 ”,” 、 ”.” 、 ” “ 都作為分個符號才能完整分割。這邊我們建立一個陣列變數 Str2_Array= Str2.Split(",|.| ".ToArray()) or Str2.Split({","c,"."c," "c}) ,這個陣列變數就會儲存分割出來的結果。我們接下來用 For each 與 Write Line 將陣列的每一項內容印出來,就可以知道我們分割的結果有沒有成功。 3       字串的合併 (Array 字串元素合併 ) 我們首先建了一個字串變數 Str3_Array= {"John","Jimmy","Shawn","Alan"} ,我們現在想把這些人名中間用 ”|” 符號隔開並且變成一個字串,這裡我們是用 String.Join( 連接符號 , 陣列 ) 這個函數達到這個目的。我們建立一個變數 Str3_Join ,使 Str3_Join=String.Join("|", Str3_Array) ,此時 Str3_Join 的結果就會是 John|Jimmy|Shawn|Alan 。我們接下來用 Write...

RPA-Uipath(5)-如何讀取Mail與取得Mail的資訊

本篇主要介紹 Uipath 取得 mail 相關資訊與附件的方法,因為 mail 的種類眾多,本範例以 Gmail 為例。首先在使用 Uipath 取得 Gmail 相關資訊前須對 Google 帳戶的安全性進行兩階段驗證設定,設定方式如下: Step1. 點選 ” 管理你的 Google 帳戶 ” Step2.  點選 ” 安全性 ” à ” 兩階段驗證 ” à 點選 ” 開始使用 ” Step3.  依 Google 所提示步驟,您最後會取得一組密碼,請務必將此密碼記下。 接下來要開始使用 Uipath 擷取 mail 相關資訊,一開始我們先使用 Get Password 儲存 mail 登入的密碼,此時密碼不是使用您真正的密碼而是使用剛剛兩階段驗證後取得的密碼,並儲存於變數 password 。 接下來使用 Get IMAP Mail Messages 來取得 mail 的相關資訊,在使用 Get IMAP Mail Messages 時必須在其屬性設定區塊進行一些參數設定。 Port 欄位填入 993 , Server 欄位填入 "imap.gmail.com" , Email 欄位填入您的 Email , Password 欄位填入 變數 password , Message 欄位我們用 MailMessage 變數填入 Mail 的相關資訊都會存在 MailMessage 變數中,我們可以用 For Each 迴圈逐一取得 mail 的相關資訊。 For Each 的屬性區塊部分也需要進行一些參數設定, List of item 欄位需填入 MailMessage 變數, TypeArgument 則須設定為 System.Net.Mail.MailMessage 。 設定完成後,我們先用 Write Line 將信件的主旨印出做為測試( 這邊我們只印出前 5 封信件的主旨,可在 Get IMAP Mail Messages 的屬性區塊中 Top 欄位中設定 ),如果要印出信件主旨,需要用 item.Subject 屬性,如要印出其他資訊,我們將常用的幾個列在以下表格: 最後,有些信件會附帶一些附件,我們如何將這些物件儲存下來呢 ? 這邊只需要用到 Save Attachments 即可。我們將其放在迴圈內以下載每個有附件的 mail...