標籤:參數 理解 nbsp dex erro 官方文檔 建議 nis 處理
在所有的程式中,都會遇到異常,有些異常是代碼編寫的時候產生的,在前期過程中可能會直接導致程式無法運行。這一類的異常,在編寫代碼的時候,程式可以直接排查修改。但有些異常,是在程式運行過程中產生的,可能是與使用者互動擷取的資料無法識別,也或者是網路請求失敗導致程式無法繼續等等原因。為了防止程式崩潰,這一類的錯誤,就需要程式員在編寫的時候提前考慮到並進行相應的異常處理。每一門語言基本都有自己相應的異常防禦機制,python尤其如此,不僅給了錯誤調試語句,還提供了龐大的內建異常類,讓我們可以精準的針對不同異常給出不同的處理方式。關於python中具體的異常分類資訊,可以參照官方文檔,地址如下:(在官方文檔中,內建異常還包括了警告和異常層次,建議一起看一下)
中文地址:http://python.usyiyi.cn/translate/python_352/library/exceptions.html#concrete-exceptions
英文地址:https://docs.python.org/3/library/exceptions.html#concrete-exceptions
在知道了具體的異常分類後,需要討論的是預測有異常發生的時候,應該如何處理,python的異常防禦相對十分簡單,常用只有三條語句,並且在調試的時候無需全部使用。先看一個簡單的調試語句:
try: print(name) #列印變數name的值except Exception:#如果有異常則輸出警示 EXception可以捕獲python中任意異常,它屬於異常基類 print("Error !")"""輸出結果如下/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/penglong/Documents/python/s10/day4/異常處理.pyError !Process finished with exit code 0 """
代碼如上所示,是一個簡單異常處理,代碼模組為try-except。try的代碼內容為業務模組,except 後接需要捕獲的異常類型,上面的代碼為了示範,直接使用了基類,在實際運用中我們常常需要捕獲具體異常類,然後給出特定的處理方式,具體為在下一份代碼中說明。except下屬的代碼為捕獲異常後的處理模組。在簡單示範了一個異常處理後,下面看一份稍微複雜的異常處理,同時會提到關於異常處理的另外兩條語句
namlist = [‘test1‘,‘test2‘]#定義一個數組,長度為2try: print (namlist[3])#在try的代碼塊嘗試列印namlist[3] 很明顯下標越界except NameError as error:#嘗試捕獲NameError,並將其列印資訊賦給error
#NameError的具體定義參見官方文檔。下同 print("NameError:",error)#在except的代碼塊 列印捕獲的異常資訊except IndexError as error:#在嘗試捕獲上一個異常之後,直接嘗試捕獲另一個異常。 print ("IndexError:",error)except Exception as error:#再次嘗試 print ("Exception:",error)else:#else語句,此處的用法是接在exception後面。如果我們預測的異常一個都未捕獲到,則執行該語句的代碼模組
#在本段代碼中,這個語句是不可能執行的,因為嘗試捕獲了Exception異常類。僅僅是說明使用方法 print("如果你一個也沒抓到,那我歸你好啦")finally:#finally語句,接在異常防禦的最後,可以跳過else直接使用。不管有沒有捕獲異常,他的下屬程式碼片段都會執行 print("不管你抓沒抓到,我都在喔")"""輸出結果如下/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/penglong/Documents/python/s10/day4/異常處理.pyIndexError: list index out of range不管你抓沒抓到,我都在喔Process finished with exit code 0
從上面的輸出資訊可以看到,我們捕獲到了一個IndexError,並且程式最終執行了finally的代碼模組。以上基本就是python的常規異常處理了。除了不可控的異常出現之外,有些代碼需要特定的運行條件,那麼,我們可以認為拋出異常。python中拋異常的方式有兩種,斷言,或者raise語句。其中,斷言需要判定條件,而raise是直接後接需要拋出的異常類型。二者應用場合在我的理解中略有分別,斷言常常使用於根據條件成立來決定拋異常的與否。例如,一個變數初始值為空白,在程式運行到一半它從網路擷取資料,如果沒有資料,那麼,程式無法執行。就可以使用斷言來判定變數是否為空白,如果為空白,則直接拋異常,並給出警示。當然,raise可以實現同樣功能,不過它需要一個if判別。因此,在代碼使用上來講,斷言更為簡潔,並且它也能被exception捕獲。我們首先來看下斷言機制:
num1 = 1 #定義倆變數num2 = 1"""斷言關鍵字使用,後接判定條件,如果條件成立,則無異常。不成立,拋異常。
用","分割,後接給出的警示資訊。警示資訊也可以省略"""assert num1 + num2 == 3, "腦子是個好東西,我希望你有一個。好好計算!" print("對啦")"""輸出結果/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/penglong/Documents/python/s10/day4/異常處理.pyTraceback (most recent call last): File "/Users/penglong/Documents/python/s10/day4/異常處理.py", line 20, in <module> assert num1 + num2 == 3, "腦子是個好東西,我希望你有一個。好好計算!"AssertionError: 腦子是個好東西,我希望你有一個。好好計算!Process finished with exit code 1"""
#####斷言異常捕獲測試########num1 = 1num2 = 1try: assert num1 + num2 == 3, "腦子是個好東西,我希望你有一個。好好計算!"except AssertionError as error: print(error)"""輸出結果/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/penglong/Documents/python/s10/day4/異常處理.py腦子是個好東西,我希望你有一個。好好計算!Process finished with exit code 0"""#可以看到列印資訊為我們定義的警示資訊
如上,代碼給的條件是明顯不成立的,所以程式輸出了異常。使用上來講,斷言的語句用於已知的條件調試相對簡潔。上面的代碼異常屬於計算錯誤,並且警示資訊屬於自訂。但有些異常時python定義的異常類裡面存在的,為了方便快捷,我們可以直接拋出,無需定義異常資訊,這時就需要raise來解決了。簡單代碼如下:
raise NameError("name error!")#拋出一個NameError異常,可以給一個列印資訊,也可以不給#常規自訂具體異常資訊應該盡量拋Exception類 這裡僅做其他類示範。print("然而並沒有錯誤!")#拋出異常後嘗試列印點神馬"""輸出結果/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/penglong/Documents/python/s10/day4/異常處理.pyTraceback (most recent call last): File "/Users/penglong/Documents/python/s10/day4/異常處理.py", line 31, in <module> raise NameErrorNameError: name error!#如果沒給參數,則沒有具體錯誤資訊Process finished with exit code 1"""
如上,raise可以直接拋出python內建的異常類,一看就知道哪裡出了錯誤,所以如果不需要條件判定的是自訂異常資訊,盡量拋Exception類。這樣不至於混淆異常資訊。以上代碼都立足於功能示範,在實際使用中,一旦拋出異常,程式就會崩潰。所以常規的拋異常大多用於代碼調試。如果是為了預防未知資訊,拋異常應該出現try--except語句的try下屬代碼模組,然後用except捕獲,再給出相應的解決方案。
以上是python的常見異常處理機制,python的異常類繁多,基本可以滿足日常需要。對於異常的文章,大部分會討論到自訂異常,但我尚未遇到需要自訂異常的情況,往往簡單的自訂警示資訊等需求都能用內建來直接更改。當然,很多測試情境確實需要更為精確的異常資訊,那麼可能需要自己重新建立一個異常類別模組,在本文暫不討論。值得一提的是,很多模組可以在python的開源論壇上可以找到,如果確實需要,不妨先去找一下。
python的異常處理