Python 斷言和異常
<font color=red size=4>Python斷言</font>
斷言是一種理智檢查,當程序的測試完成,能夠將其打開或關閉。斷言的最簡單方法就是把它比做raise-if語句(或更加準確,raise-if-not聲明)。一個表達式進行測試,若是結果出現false,將引起異常。程序中經常放置斷言來檢查輸入的有效與否,或在一個函數調用後檢查有效的輸出,其爲assert關鍵字構成的語句。 assert語句</font> 但它遇到一個斷言語句,Python評估計算以後的表達式,但願是true。若是是表達式爲false,Python觸發AssertionError異常,其語法是:python
assert Expression[, Arguments]
若是斷言失敗,Python使用ArgumentExpression做爲AssetionError異常的參數,AssertionError能夠被捕獲,並用try-except語句處理,相似其餘異常。可是若是沒有處理它們,將終止改爲程序併產生一個回溯。以下實例:函數
def kelvin_to_fahrenheit(temperature): assert temperature >= 0, "Colder than absolute zero!" return ((temperature-273)*1.8)+32 print(kelvin_to_fahrenheit(273)) print(kelvin_to_fahrenheit(505.78)) print(kelvin_to_fahrenheit(-5))
運行輸出結果爲:測試
32.0 451.00399999999996 Traceback (most recent call last): File "D:/PythonCode/basic knowledge/exceptions.py", line 8, in <module> print(kelvin_to_fahrenheit(-5)) File "D:/PythonCode/basic knowledge/exceptions.py", line 2, in kelvin_to_fahrenheit assert temperature >= 0, "Colder than absolute zero!" AssertionError: Colder than absolute zero!
<font color=red size=4>Python 異常處理</font>
Python提供的標準異常以下列表:spa
異常名稱 | 描述 |
---|---|
Exception | 全部異常的基類 |
StopIteration | 當一個迭代器的next()方法不能指向任何對象時引起 |
SystemExit | 由sys.exit()函數引起 |
StandardError | 除了StopIteration異常和SystemExit,全部內置異常的基類 |
ArithmeticError | 數值計算所發生的全部異常的基類 |
OverflowError | 當數字類型計算超過最高限額引起 |
FloatingPointError | 當一個浮點運算失敗時觸發 |
ZeroDivisonError | 當除運算或模零在全部數值類型運算時引起 |
AssertionError | 斷言語句失敗的狀況下引起 |
AttributeError | 屬性引用或賦值失敗的狀況下引起 |
EOFError | 當從 raw_input() 與 input() 函數輸入,到達文件末尾時觸發 |
ImportError | 當一個 import 語句失敗時觸發 |
KeyboardInterrupt | 當用戶中斷程序執行,一般是經過按 Ctrl+c 引起 |
LookupError | 全部查找錯誤基類 |
IndexError、KeyError | 當在一個序列中沒有找到一個索引時引起;當指定的鍵沒有在字典中找到引起 |
NameError | 當在局部或全局命名空間中找不到的標識引起 |
UnboundLocalError | 試圖訪問在函數或方法的局部變量時引起,但沒有值分配給它 |
EnvironmentError | Python環境以外發生的全部異常的基類。 |
IOError | 當一個輸入/輸出操做失敗,如打印語句或 open()函數試圖打開不存在的文件時引起;操做系統相關的錯誤時引起 |
SyntaxError、IndentationError | 當在Python語法錯誤引起;沒有正確指定縮進引起 |
SystemError、SystemExit | 當解釋器發現一個內部問題,但遇到此錯誤時,Python解釋器不退出引起;當Python解釋器不使用sys.exit()函數引起。若是代碼沒有被處理,解釋器會退出 |
ValueError | 在內置函數對於數據類型,參數的有效類型時引起,可是參數指定了無效值 |
RuntimeError | 當生成的錯誤不屬於任何類別時引起 |
NotImplementedError | 當要在繼承的類來實現,抽象方法實際上沒有實現時引起此異常 |
什麼是異常 異常是一個事件,在程序的執行過程當中擾亂程序的正常流程。通常來講,當Python程序遇到某種狀況,它沒法應付則會引起一個異常。操作系統
異常處理 咱們可使用try/except語句來捕捉異常,try/except語句用來檢測try語句塊中的異常,從而讓except語句捕獲異常信息並處理。若是咱們不想在異常發生時程序結束,只須要在except裏捕獲它,其語法格式以下:code
try: <statement> except <name>: <statement> except <name>, <data>: <statement> else: <statement>
try的工做原理,當開始一個try語句後,Python就在當前程序的上下文中作標記,這樣當異常出現時,就能夠回到這裏,try子句先執行,接下來會發生什麼依賴於執行時是否出現異常。對象
- 若是try後的語句執行時發生異常,Python就跳回到try並執行第一個匹配該異常的except子句,異常處理完畢,控制流就經過整個try語句(除非在處理異常時又引起新的異常);
- 若是try後的語句裏發生了異常,卻沒有匹配的except子句,異常將被遞交到上層的try,或者到程序的最上層(這樣將結束程序,並打印缺省的出錯信息);
- 若是try子句執行時沒有發生異常,Python將執行else語句後的語句(若是有else的話),而後控制流經過整個try語句;
如下實例,打開文件,在該文件中寫入內容,並未發生異常:繼承
try: fh = open("testfile.txt", "w", encoding="utf-8") fh.write("這是一個測試文件,用於測試異常!") except IOError: print("Error:沒有找到文件或讀取文件失敗!") else: print("內容寫入文件成功!") fh.close()
運行輸出結果爲:索引
內容寫入文件成功! # 查看文件內容 這是一個測試文件,用於測試異常!
如下實例,打開文件,在該文件中寫入內容,但文件沒有寫入權限,發生了異常(Linux環境下):事件
try: fh = open("testfile", "w") fh.write("這是一個測試文件,用於測試異常!!") except IOError: print("Error: 沒有找到文件或讀取文件失敗") else: print("內容寫入文件成功") fh.close()
在執行代碼前爲了測試方便,咱們能夠先去掉testfile.txt文件的寫權限,命令以下:
chmod -w testfile.txt
在運行上面代碼輸出結果爲:
Error: 沒有找到文件或讀取文件失敗
使用except而不帶任何異常類型 咱們能夠不帶任何異常類型使用except,語法以下:
try 正常的操做 ................. except: 發生異常,執行這部分代碼 ................. else: 若是沒有異常執行這部分代碼
以上方式try-except語句捕獲全部發生的異常,可是這不是一個好的方式,咱們沒法經過該程序識別出具體的異常信息,由於它捕獲全部的異常。
使用except而帶多種異常類型 咱們可使用相同的except語句來處理多個異常信息,以下所示:
try: 正常的操做 ...................... except(Exception1[, Exception2[,...ExceptionN]]]): 發生以上多個異常中的一個,執行這塊代碼 ...................... else: 若是沒有異常執行這塊代碼
try-finally語句 try-finally語句不管是否發生異常都將執行finally後的代碼:
try: <語句> finally: <語句> #退出try時總會執行 raise
以下實例:
try: fh = open("testfile", "w") fh.write("這是一個測試文件,用於測試異常!!") finally: print("Error: 沒有找到文件或讀取文件失敗")
若是打開的文件沒有可寫權限,輸出結果以下:
Error: 沒有找到文件或讀取文件失敗
上面實例,也能夠寫成以下的方式:
try: fh = open("testfile", "w") try: fh.write("這是一個測試文件,用於測試異常!!") finally: print("關閉文件") fh.close() except IOError: print("Error: 沒有找到文件或讀取文件失敗")
當在try塊中拋出一個異常,當即執行finally代碼塊。finally塊中的全部語句執行後,異常被再次觸發,並執行except代碼塊。
異常的參數 一個異常能夠帶上參數,能夠做爲輸出的異常信息參數,咱們能夠經過except語句來捕獲異常的參數,以下所示:
try: 正常的操做 ...................... except ExceptionType, Argument: 你能夠在這輸出 Argument 的值...
變量接受的異常值一般包含在異常的語句中。在元組的表單中變量能夠接收一個或多個值。元組一般包含錯誤字符串,錯誤數字,錯誤位置。 如下爲單個異常的實例:
def temp_convert(var): try: return int(var) except ValueError as argument: #Python3 print("參數沒有包含數字\n", argument) temp_convert("abc")
運行輸出結果爲:
參數沒有包含數字 invalid literal for int() with base 10: 'abc'
觸發異常 咱們可使用raise語句本身觸發異常,其語法格式以下:
raise [Exception [, args [, traceback]]]
語句中Exception是異常的類型(例如:NameError)參數標準異常中任一種,args是本身提供的異常參數。最後一個參數是可選的(實際中不多用),若是存在,是跟蹤異常對象。
實例:一個異常能夠是字符串,類或對象。Python提供的內置異常,大多數都是實例化的類,這是一個類的的實例的參數,異常的定義很是簡單,以下所示:
def function_name(level): if level < 1: raise Exception("Invalid level!", level) # 觸發異常,後面的代碼就不會再執行
**注意:**爲了可以捕獲異常,except語句必須用相同的異常來拋出類對象或字符串,例如:咱們捕獲上面異常,except語句以下所示:
try: 正常邏輯 except Exception as err: 觸發自定義異常 else: 其他代碼
以下實例:
def function_name(level): if level < 1: raise Exception("Invalid level!", level) # 觸發異常,後面的代碼就不會再執行 try: function_name(0) except Exception as err: print(1, err) else: print(2)
運行輸出結果爲:
1 ('Invalid level!', 0)
用戶自定義異常 經過建立一個新的異常類,程序能夠命名它們本身的異常。異常應該是典型的繼承自Exception類,經過直接或間接的方式。如下爲與RuntimeError相關的實例,實例中建立了一個類,基類爲RuntimeError,用於在異常觸發時輸出更多的信息,在try語句塊中,用戶自定義的異常後執行except塊語句,變量e用於建立NetworkError類的實例:
class NetworkError(RuntimeError): def __init__(self, arg): self.args = arg
在定義以上類後,咱們能夠觸發該異常,以下所示:
try: raise NetworkError("Bad hostname") except NetworkError as e: print(e.args)