- 來源 | 願碼(ChainDesk.CN)內容編輯
- 願碼Slogan | 鏈接每一個程序員的故事
- 網站 | http://chaindesk.cn
- 願碼願景 | 打造全學科IT系統免費課程,助力小白用戶、初級工程師0成本免費系統學習、低成本進階,幫助BAT一線資深工程師成長並利用自身優點創造睡後收入。
- 官方公衆號 | 願碼 | 願碼服務號 | 區塊鏈部落
- 免費加入願碼全思惟工程師社羣 | 任一公衆號回覆「願碼」兩個字獲取入羣二維碼
本文閱讀時長:10minpython
本文所涉及知識點程序員
在直接進入代碼並解決這些問題以前,讓咱們首先了解異常是什麼以及處理異常是什麼意思。數據庫
異常是Python中的對象。它爲咱們提供了有關在程序執行期間檢測到的錯誤的信息。在調試應用程序時注意到的錯誤是未處理的異常,由於咱們沒有這些異常。在本文後面,您將學習處理這些異常的技巧。函數
在早期回溯中看到的ValueError和IndexError異常是Python中內置異常類型的示例 。在下一節中,您將瞭解Python支持的其餘一些內置異常 。學習
讓咱們快速回顧一些最常遇到的異常。最簡單的方法是嘗試運行一些錯誤的代碼,讓它報告錯誤回溯的問題!啓動Python解釋器並編寫如下代碼:區塊鏈
如下是一些異常狀況:測試
正如您所看到的,代碼的每一行都會拋出一個帶有異常類型的錯誤回溯(突出顯示)。這些是Python中的一些內置異常。Python提供BaseException做爲全部內置異常的基類。可是,大多數內置異常不直接繼承BaseException。相反,它們是從一個名爲Exception的類派生而來的,而這個類又繼承自BaseException。處理程序退出的內置異常(例如,SystemExit)直接從BaseException派生。您還能夠建立本身的異常類做爲Exception的子類。您將在本文後面瞭解到這一點。網站
到目前爲止,咱們已經看到了異常的發生方式 如今,是時候學習如何使用try ... except子句來處理這些異常。如下僞代碼顯示了try ... except子句的一個很是簡單的示例:spa
咱們來看看前面的代碼片斷:調試
· 首先,程序嘗試執行try子句中的代碼。
· 在執行期間,若是出現錯誤(若是發生異常),它將跳出此try子句。try塊中的其他代碼不會被執行。
· 而後,它在except子句中查找適當的異常處理程序並執行它。
這裏使用的 except子句是通用的。它將捕獲try子句中發生的全部類型的異常。而不是擁有這個「全能」處理程序,更好的作法是捕獲您預期的錯誤並編寫特定於這些錯誤的異常處理代碼。例如,try子句中的代碼可能會拋出AssertionError。您能夠編寫特定的異常處理程序,而不是使用universal except子句,以下所示:
在這裏,咱們有一個except子句專門處理AssertionError。它還意味着除了AssertionError以外的任何錯誤都將做爲未處理的異常漏掉。爲此,咱們須要使用不一樣的異常處理程序定義多個except子句。可是,在任什麼時候候,只會調用一個異常處理程序。用一個例子能夠更好地解釋這一點。咱們來看看下面的代碼片斷:
該試塊調用solve_something() 。此函數接受一個數字做爲用戶輸入,並斷言該數字大於零。若是斷言失敗,它會直接跳轉處處理程序,但AssertionError除外。
在另外一個場景中,若是> 0,則執行solve_something()中的其他代碼。您會注意到未定義變量x,這會致使NameError。此異常由另外一個異常子句處理,但NameError除外。一樣,您能夠爲預期的錯誤定義特定的異常處理程序。
Python中的raise關鍵字用於強制發生異常。換句話說,它引起了一個異常。語法很簡單; 只需打開Python解釋器並輸入:
>>> raise AssertionError("some error message")
這會產生如下錯誤回溯:
Traceback (most recent call last): File "", line 1, in AssertionError : some error message
在某些狀況下,咱們須要從新引起異常。假設,在try子句中,您有一個將數字除以零的表達式。在普通算術中,這個表達沒有意義。這是一個錯誤!這會致使程序引起一個名爲ZeroDivisionError的異常。若是沒有異常處理代碼,程序將只打印錯誤消息並終止。
若是您但願將此錯誤寫入某個日誌文件而後終止該程序,該怎麼辦?在這裏,您可使用except子句首先記錄錯誤。而後,使用不帶任何參數的raise關鍵字來從新引起異常。異常將在堆棧中向上傳播。在此示例中,它終止程序。可使用raise關鍵字從新引起異常而不使用任何參數。
這是一個示例,顯示如何從新引起異常:
能夠看出,在解決a / b表達式時,會出現zeroexception的adivision。這是由於變量b的值設置爲0。出於說明目的,咱們假設此錯誤沒有特定的異常處理程序。所以,咱們將使用general except子句,在記錄錯誤後從新引起異常。若是您想本身嘗試,只需在新的Python文件中編寫前面說明的代碼,而後從終端窗口運行它。如下屏幕截圖顯示了上述代碼的輸出:
能夠在try ... except子句中指定可選的else塊。在其餘的只發生ifno異常塊被執行的嘗試......除了條款。語法以下:
在其餘塊的前執行最後條款,咱們將在接下來的學習。
還有其餘東西能夠添加到try ...除了... else story:一個可選的finally子句。顧名思義,此子句中的代碼在關聯的try ... except塊的末尾執行。不管是否引起異常,finally子句(若是指定)將在try ... except子句的末尾執行。想象一下它是由Python提供的全天候保證!如下代碼段顯示了finally塊的運行狀況:
運行這個簡單的代碼將產生如下輸出:
$ python finally_example1.py Enter a number: -1 Uh oh..Assertion Error. Do some special cleanup
輸出中的最後一行是finally子句中的print語句。
帶有和不帶finally子句的代碼片斷以下面的屏幕截圖所示。即便except子句指示代碼從函數返回,也確保finally子句中的代碼最終執行。
在最後條款一般用於離開功能以前執行清理任務。示例用例是關閉數據庫鏈接或文件。但請注意,爲此,您還能夠在Python中使用with語句。
建立一個從Exception派生的新異常類是微不足道的。打開Python解釋器並建立如下類:
>>> class GameUnitError(Exception): ... pass ... >>>
就這樣!咱們有一個新的異常類GameUnitError,能夠部署了。如何測試此異常?在Python解釋器中鍵入如下代碼行:
>>> raise GameUnitError("ERROR: some problem with game unit")
引起新建立的異常將打印如下回溯:
>>> raise GameUnitError("ERROR: some problem with game unit") Traceback (most recent call last): File "", line 1, in __main__.GameUnitError: ERROR: some problem with game unit
將GameUnitError類複製到其本身的模塊gameuniterror.py中,並將其保存在與attackoftheorcs_v1_1.py相同的目錄中。
接下來,更新attackoftheorcs_v1_1.py文件以包含如下更改:
首先,在文件的開頭添加如下import語句:
from gameuniterror import GameUnitError
第二個變化是在AbstractGameUnit.heal方法中。更新後的代碼顯示在如下代碼段中。觀察高亮代碼,只要提出的價值自定義異常self.health_meter超過的self.max_hp。
經過這兩個更改,運行以前建立的heal_exception_example.py。您將看到引起新的異常,如如下屏幕截圖所示:
咱們能夠用GameUnitError類作更多的事情嗎?固然!就像任何其餘類同樣,咱們能夠定義屬性並使用它們。讓咱們進一步擴展這個課程。在修改後的版本中,它將接受一個額外的參數和一些預約義的錯誤代碼。更新的GameUnitError類顯示在如下屏幕截圖中:
咱們來看看前面屏幕截圖中的代碼:
· 首先,它調用Exception超類的__init__方法,而後定義一些額外的實例變量。
· 一個新的dictionary對象self。error_dict將錯誤整數代碼和錯誤信息保存爲鍵值對。
· 該self.error_message存儲有關根據提供的錯誤代碼當前錯誤的信息。
· 在嘗試......除了子句確保error_dict實際上已經由指定的鍵碼的說法。它不在except子句中,咱們只是檢索默認錯誤代碼爲000的值。
到目前爲止,咱們已經對GameUnitError類和AbstractGameUnit.heal方法進行了更改。咱們尚未完成。拼圖的最後一塊是修改主要在程序heal_exception_example.py文件。代碼顯示在如下屏幕截圖中:
咱們來看看代碼:
· 因爲heal_by值太大,try子句中的heal方法會引起GameUnitError異常。
· new except子句處理GameUnitError異常,就像任何其餘內置異常同樣。
· 在except子句中,咱們有兩個print語句。第一個打印health_meter> max_hp!(回想一下,當在heal方法中引起此異常時,此字符串被做爲GameUnitError實例的第一個參數給出)。第二個print語句檢索並打印GameUnitError實例的error_message屬性。
咱們已經作好了全部的改變。咱們能夠在終端窗口中運行此示例:
$ python heal_exception_example.py
該程序的輸出顯示在如下屏幕截圖中:
在這個簡單的例子中,將錯誤信息打印到控制檯。您能夠進一步將詳細錯誤日誌寫入文件,並跟蹤應用程序運行時生成的全部錯誤消息。