Python程式設計中的錯誤與異常

2021-10-06 15:15:11 字數 3976 閱讀 8095

到目前為止,我們還沒有提到錯誤訊息,但是如果你已經嘗試過那些例子,你可能已經看過了一些錯誤訊息。 目前(至少)有兩種可區分的錯誤:語法錯誤 和 異常。

語法錯誤

語法錯誤又稱解析錯誤,可能是你在學習python 時最容易遇到的錯誤:

python程式設計中的錯誤與異常

解析器會輸出出現語法錯誤的那一行,並顯示乙個「箭頭」,指向這行裡面檢測到第乙個錯誤。 錯誤是由箭頭指示的位置 上面 的 token 引起的(或者至少是在這裡被檢測出的):在示例中,在 print() 這個函式中檢測到了錯誤,因為在它前面少了個冒號 (』:』) 。檔名和行號也會被輸出,以便輸入來自指令碼檔案時你能知道去哪檢查。

異常即使語句或表示式在語法上是正確的,但在嘗試執行時,它仍可能會引發錯誤。 在執行時檢測到的錯誤被稱為異常,異常不一定會導致嚴重後果:你將很快學會如何在python程式中處理它們。 但是,大多數異常並不會被程式處理,此時會顯示如下所示的錯誤資訊:

python程式設計中的錯誤與異常

錯誤資訊的最後一行告訴我們程式遇到了什麼型別的錯誤。異常有不同的型別,而其型別名稱將會作為錯誤資訊的一部分中列印出來:上述示例中的異常型別依次是:zerodivisionerror, nameerror 和 typeerror。作為異常型別列印的字串是發生的內建異常的名稱。對於所有內建異常都是如此,但對於使用者定義的異常則不一定如此(雖然這是乙個有用的規範)。標準的異常型別是內建的識別符號(而不是保留關鍵字)。

這一行的剩下的部分根據異常型別及其原因提供詳細資訊。

錯誤資訊的前一部分以堆疊回溯的形式顯示發生異常時的上下文。通常它包含列出源**行的堆疊回溯;但是它不會顯示從標準輸入中讀取的行。

內建異常 列出了內建異常和它們的含義。

處理異常

可以編寫處理所選異常的程式。請看下面的例子,它會要求使用者一直輸入,直到輸入的是乙個有效的整數,但允許使用者中斷程式(使用 control-c 或作業系統支援的其他操作);請注意使用者引起的中斷可以通過引發 keyboardinterrupt 異常來指示。:

python程式設計中的錯誤與異常

try 語句的工作原理如下。

首先,執行 try 子句 (try 和 except 關鍵字之間的(多行)語句)。

如果沒有異常發生,則跳過 except 子句 並完成 try 語句的執行。

如果在執行try 子句時發生了異常,則跳過該子句中剩下的部分。然後,如果異常的型別和 except 關鍵字後面的異常匹配,則執行 except 子句 ,然後繼續執行 try 語句之後的**。

如果發生的異常和 except 子句中指定的異常不匹配,則將其傳遞到外部的 try 語句中;如果沒有找到處理程式,則它是乙個 未處理異常,執行將停止並顯示如上所示的訊息。

乙個 try 語句可能有多個 except 子句,以指定不同異常的處理程式。 最多會執行乙個處理程式。 處理程式只處理相應的 try 子句中發生的異常,而不處理同一 try 語句內其他處理程式中的異常。 乙個 except 子句可以將多個異常命名為帶括號的元組,例如:

… except (runtimeerror, typeerror, nameerror):

… pass

如果發生的異常和 except 子句中的類是同乙個類或者是它的基類,則異常和except子句中的類是相容的(但反過來則不成立 — 列出派生類的except 子句與基類相容)。例如,下面的**將依次列印 b, c, d

python程式設計中的錯誤與異常

請注意如果 except 子句被顛倒(把 except b 放到第乙個),它將列印 b,b,b — 即第乙個匹配的 except 子句被觸發。

最後的 except 子句可以省略異常名,以用作萬用字元。但請謹慎使用,因為以這種方式很容易掩蓋真正的程式設計錯誤!它還可用於列印錯誤訊息,然後重新引發異常(同樣允許呼叫者處理異常):

python程式設計中的錯誤與異常

try … except 語句有乙個可選的 else 子句,在使用時必須放在所有的 except 子句後面。對於在try 子句不引發異常時必須執行的**來說很有用。例如:

python程式設計中的錯誤與異常

使用 else 子句比向 try 子句新增額外的**要好,因為它避免了意外捕獲由 try … except 語句保護的**未引發的異常。

發生異常時,它可能具有關聯值,也稱為異常 引數 。引數的存在和型別取決於異常型別。

except 子句可以在異常名稱後面指定乙個變數。這個變數和乙個異常例項繫結,它的引數儲存在 instance.args 中。為了方便起見,異常例項定義了str() ,因此可以直接列印引數而無需引用 .args 。也可以在丟擲之前首先例項化異常,並根據需要向其新增任何屬性。:

python程式設計中的錯誤與異常

如果異常有引數,則它們將作為未處理異常的訊息的最後一部分(『詳細資訊』)列印。

異常處理程式不僅處理 try 子句中遇到的異常,還處理 try 子句中呼叫(即使是間接地)的函式內部發生的異常。例如:

python程式設計中的錯誤與異常

丟擲異常

raise 語句允許程式設計師強制發生指定的異常。例如:

raise nameerror(『hithere』)

traceback (most recent call last):

file 「」, line 1, in

nameerror: hithere

raise 唯一的引數就是要丟擲的異常。這個引數必須是乙個異常例項或者是乙個異常類(派生自 exception 的類)。如果傳遞的是乙個異常類,它將通過呼叫沒有引數的建構函式來隱式例項化:

raise valueerror # shorthand for 『raise valueerror()』

如果你需要確定是否引發了異常但不打算處理它,則可以使用更簡單的 raise 語句形式重新引發異常

python程式設計中的錯誤與異常

使用者自定義異常

程式可以通過建立新的異常類來命名它們自己的異常(有關python 類的更多資訊,請參閱 類)。異常通常應該直接或間接地從 exception 類派生。

可以定義異常類,它可以執行任何其他類可以執行的任何操作,但通常保持簡單,通常只提供許多屬性,這些屬性允許處理程式為異常提取有關錯誤的資訊。在建立可能引發多個不同錯誤的模組時,通常的做法是為該模組定義的異常建立基類,並為不同錯誤條件建立特定異常類的子類:

python程式設計中的錯誤與異常

大多數異常都定義為名稱以「error」結尾,類似於標準異常的命名。

許多標準模組定義了它們自己的異常,以報告它們定義的函式中可能出現的錯誤。有關類的更多資訊,請參見類 類。

定義清理操作

try 語句有另乙個可選子句,用於定義必須在所有情況下執行的清理操作。例如:

python程式設計中的錯誤與異常

正如你所看到的,finally 子句在任何情況下都會被執行。 兩個字串相除所引發的 typeerror 不會由 except 子句處理,因此會在 finally 子句執行後被重新引發。

在實際應用程式中,finally 子句對於釋放外部資源(例如檔案或者網路連線)非常有用,無論是否成功使用資源。

預定義的清理操作

某些物件定義了在不再需要該物件時要執行的標準清理操作,無論使用該物件的操作是成功還是失敗。請檢視下面的示例,它嘗試開啟乙個檔案並把其內容列印到螢幕上。:

for line in open(「myfile.txt」):

print(line, end="")

這個**的問題在於,它在這部分**執行完後,會使檔案在一段不確定的時間內處於開啟狀態。這在簡單指令碼中不是問題,但對於較大的應用程式來說可能是個問題。 with 語句允許像檔案這樣的物件能夠以一種確保它們得到及時和正確的清理的方式使用。:

with open(「myfile.txt」) as f:

for line in f:

print(line, end="")

執行完語句後,即使在處理行時遇到問題,檔案 f 也始終會被關閉。和檔案一樣,提供預定義清理操作的物件將在其文件中指出這一點。

python程式設計 5 錯誤與異常

1 異常處理 import sys try f open myfile.txt s f.readline i int s.strip except oserror as err print os error format err except valueerror print could not c...

python錯誤異常 python中的錯誤異常處理

這是我的 class persondata def init self,age,spouse none,children 0 self.age age self.children children self.spouse spouse if self.spouse none del self.spo...

python 錯誤與異常

錯誤在執行前修改,邏輯錯誤無法修改 執行時,異常產生,檢查到錯誤且直譯器認為是異常,丟擲異常 異常處理,截獲異常,忽略或者終止程式處理異常 try try suite except exception e exception blocktry aexcept nameerror,e print ca...