Python Tutorial(八):錯誤和異常

來源:互聯網
上載者:User

直到現在錯誤訊息還沒有被提起,但是如果你嘗試了樣本的話你可能已經看到一些。這是(至少)兩種可區別的錯誤,語法錯誤和異常。

8.1 語法錯誤

語法錯誤,也被稱為解析錯誤,也許是你得到的最普通類型的抱怨當你仍然在學習Python的時候:

解析器重複錯誤行,並在本行最先檢測到錯誤的地方顯示一個小箭頭。錯誤是由箭頭前面的標記引起的。樣本中錯誤在函數print()處被檢測出來,因為它前面少了一個冒號。檔案名稱和行號被列印出來,所以你知道應該去輸入指令碼的哪個地方尋找情況。

8.2 異常

即使一個語句或運算式在文法上是正確的,在嘗試運行它時也可能引發一個錯誤。在運行期被檢測到的錯誤稱為異常,並不是無條件致命的,稍後你會學習如何在Python程式中處理它們。許多異常沒有被程式處理,然而,會導致下面的錯誤訊息:

錯誤訊息的最後一行指示發生了什麼。異常有不同的類型,類型作為訊息的一部分被列印出來,樣本中的類型是 除零錯誤,名稱錯誤和類型錯誤。作為異常類型被列印的字串是發生的內建異常的名字。對於所有的內建異常這都是真的,但是對於使用者定義的異常不一定是真的。標準的異常名稱是內建的標識符(不是保留關鍵字)。

本行其餘的內容提供了基於異常的類型和是什麼引發它的詳細資料。

錯誤訊息的前面部分顯示了異常發生位置的上下文,以堆疊追蹤的形式。一般情況下,它包含列出源檔案行的堆疊追蹤,它將不顯示從標準輸入讀到的行。

8.3 處理異常

可以寫程式來處理選定的異常。看下面的樣本,要求使用者輸,直到一個合法的整數被鍵入,但是允許使用者中斷程式,一個使用者產生的中斷被用訊號發送通過引發一個異常:

try語句按如下方式工作

  • 首先,try從句(在關鍵字try和except之間的語句)被執行。
  • 如果沒有異常發生,except從句被跳過,try語句執行完畢。
  • 如果在執行try語句的時候有異常發生,剩餘的語句會被跳過。如果它的類型和except後面的命名異常相匹配,這個except從句被執行,然後在try語句後面繼續執行。
  • 如果有異常發生,並且它和except從句中的命名異常類型不符,它被傳遞到外層的try語句,如果沒有發現處理常式,它就是一個未處理的異常,程式停止執行,顯示上面的錯誤資訊。

一個try語句或許有多個except從句,來為不同的異常指定處理常式。至多一個處理常式將被執行。處理常式只處理髮生在相應try從句中的異常,而不處理髮生在同一個try語句的其它處理常式中的異常。一個except從句可以命名多個異常,使用一個括弧元組,例如:

最後一個except從句或許可以忽略異常的名字,作為萬用字元。這樣使用應該極其謹慎,因為這樣容易掩飾掉一個真正的編程錯誤。它也可以被用來列印一個錯誤資訊,然後重新引發這個異常(也允許調用者來處理這個異常):

try...except語句有一個可選的else從句,如果有的話必須跟在所有的except從句後面。對於那些異常沒有發生時必須執行的代碼非常有用。例如:

else從句的使用比往try從句裡添加額外的代碼要好,因為它避免了意外的捕獲一個異常,並不是被try...except語句保護的代碼所引起的。

當一個異常發生時,它或許有一個關聯的值,也被稱為異常的參數。這個參數的出現和類型取決與異常的類型。

except從句可以在異常名稱後面指定一個變數。這個變數綁定到一個異常執行個體,並且參數被儲存在instance.args裡。為了方便,異常執行個體定義了__str__()函數,所以參數可以被直接的列印出來而不用引用.args。你可以在引發前首先執行個體化一個異常,並且添加任何渴望的屬性:

如果一個異常有參數,對於未處理的異常,它們作為資訊的最後部分被列印出來。

例外處理常式並不僅僅處理那些在try從句中直接發生的異常,同樣也處理那些在try從句中調用(或間接調用)的函數裡面發生的異常。例如:

8.4 引發異常

raise語句允許程式員迫使一個指定的異常發生。例如:

raise的惟一參數指示被引發的異常。它要麼是一個異常執行個體或是一個異常類。

如果你需要決定一個異常是否被引發,但是不打算處理它,一個更簡單的raise語句形式允許你再次引發異常:

8.5 使用者定義異常

通過建立一個新的異常類,程式可以命名它們自己的異常。異常應該典型的繼承於Exception類,要麼直接的或間接地。例如:

在這個樣本裡面,Exception的預設的__init__()已經被重寫。新的行為簡單的建立一個value屬性。這替換了建立args屬性的預設行為。

異常類可以被定義做任何其它類可以做的事情,但是通常保持簡單,通常只提供一些屬性,允許有關錯誤的資訊被異常的處理常式抽取到。當建立一個能引發幾個不同錯誤的模組時,一個通用的實踐是為那個模組裡定義的所有異常建立一個基類,對於不同的錯誤情況,建立特定的異常子類:

許多異常被定義為以Error結尾的名稱,與標準異常的命名相似。

許多標準的模組定義它們自己的異常來報告可能發生在它們定義的函數裡面的錯誤。

8.6 定義清除動作

try語句有一個可選的從句,它的目的是定義在任何情況下都必須被執行的清除動作。例如:

一個finally從句在離開try語句之前總是被執行,無論一個異常發生與否。當try從句裡面發生了一個異常,並且沒有被一個except從句處理(或異常發生在except從句或else從句),它會在finally從句被執行後重新引發。當try語句的任何從句通過break,continue或return語句離開時,finally從句也會被執行。一個更複雜的樣本:

就像你看到的那樣,finally從句在任何情況下都會被執行。通過兩個字串相除而引發的TypeError沒有被except從句處理,所以在finally從句被執行後重新引發。

在現實世界的應用程式裡,finally從句對於釋放外部資源非常有用(像檔案和網路連接),不管對資源的使用是否成功。

8.7 預定義的清除動作

一些對象定義標準的清除動作來保證當對象不再被需要,不管使用對象的操作是成功或是失敗。看下面的樣本,嘗試開啟一個檔案並把它的內容列印到螢幕:

這個代碼的問題是在這部分代碼執行完後,檔案的開啟狀態持續一個不確定的時間。在簡單的指令碼裡面這不算是一個問題,但對於大的應用來說是一個問題。with語句允許像檔案這樣的對象以確保它們總是被合適的和正確的被清除的方式來使用:

在語句執行後,檔案f總是被關閉,即使在處理行時遇到了問題。像檔案這樣的,提供了預定義清除動作的對象在文檔裡將指出這一點。

本文是對官方網站內容的翻譯,原文地址:http://docs.python.org/3/tutorial/errors.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.