測試開發想通過python面試環節,必須懂得異常原理
我們先通過一個例子來了解代碼中引入異常處理的原因。
- print('Start')
- a=10
- b=0
- print(a/b)
- print('End')
執行結果
Traceback(most recent call last):
File"C:/Users/Kevin/PycharmProjects/PyDemo/p1/exception_demo.py", line 4,in print(a/b)
ZeroDivisionError:division by zero
Start
Processfinished with exit code 1
大家可以看到代碼出現了問題,這個結果是可以預見的,但是End并沒有成功打印,這說明了print('End')語句沒有被執行,所以程序中一旦出現了異常,那么異常點后面的語句是不會被執行的!
我們可以利用條件語句來解決這個問題,代碼如下:
- print('Start')
- a=10
- b=0
- if b!=0:
- print(a/b)
- print('End')
我們也可以通過python的異常處理機制來解決這個問題。在python中捕捉異常可以使用try/except語句。 try/except語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息并處理。語法:try....except的語法,代碼如下:
- print('Start')
- try:
- a=10
- b=0
- print(a / b)except:
- print("catch exception")
- print('End')
運行結果
Start
catch exception
End
大家可以看到try中的代碼print(a / b)出了異常被except捕獲,然后執行了print("catch exception"),最后程序正常執行完畢!
講到這里可能有的同學會問,明明可以用條件語句就可以解決的問題,為什么還要引入異常機制呢?最簡單的解釋就是,用異常機制會大大的減少代碼量,這個例子比較簡單大家可能體會不到,在實際編碼中try里面是會有很多行代碼的,只要有錯誤那么就會被catch住!如果使用條件語句,那么就需要在多行代碼中都進行判斷,這個代碼量可想而知!
異常的類型
異常也是分種類的,處理不同類型的錯誤,會使用不同的異常類型,python的標準異常包括:
- BaseException 所有異常的基類
- SystemExit 解釋器請求退出
- KeyboardInterrupt 用戶中斷執行
- Exception 常規錯誤的基類
- StopIteration 迭代器沒有更多的值
- GeneratorExit 生成器(generator)發生異常來通知退出
- StandardError 所有的內建標準異常的基類
- ArithmeticError 所有數值計算錯誤的基類
- FloatingPointError 浮點計算錯誤
- OverflowError 數值運算超出最大限制
- ZeroDivisionError 除(或取模)零 (所有數據類型)
- AssertionError 斷言語句失敗
- AttributeError 對象沒有這個屬性
- EOFError 沒有內建輸入,到達EOF 標記
- EnvironmentError 操作系統錯誤的基類
- IOError 輸入/輸出操作失敗
- OSError 操作系統錯誤
- WindowsError 系統調用失敗
- ImportError 導入模塊/對象失敗
- LookupError 無效數據查詢的基類
- IndexError 序列中沒有此索引(index)
- KeyError 映射中沒有這個鍵
- MemoryError 內存溢出錯誤(對于Python 解釋器不是致命的)
- NameError 未聲明/初始化對象 (沒有屬性)
- UnboundLocalError 訪問未初始化的本地變量
- ReferenceError 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象
- RuntimeError 一般的運行時錯誤
- NotImplementedError 尚未實現的方法
- SyntaxErrorPython 語法錯誤
- IndentationError 縮進錯誤
- TabErrorTab 和空格混用
- SystemError 一般的解釋器系統錯誤
- TypeError 對類型無效的操作
- ValueError 傳入無效的參數
- UnicodeErrorUnicode 相關的錯誤
- UnicodeDecodeErrorUnicode 解碼時的錯誤
- UnicodeEncodeErrorUnicode 編碼時錯誤
- UnicodeTranslateErrorUnicode 轉換時錯誤
- Warning 警告的基類
- DeprecationWarning 關于被棄用的特征的警告
- FutureWarning 關于構造將來語義會有改變的警告
- OverflowWarning 舊的關于自動提升為長整型(long)的警告
- PendingDeprecationWarning 關于特性將會被廢棄的警告
- RuntimeWarning 可疑的運行時行為(runtime behavior)的警告
- SyntaxWarning 可疑的語法的警告
- UserWarning 用戶代碼生成的警告
使用不同類別的異常無法捕獲非自身種類的異常,例如使用IOError是無法捕獲ZeroDivisionError的,代碼如下:
- print('Start')
- try:
- a=10
- b=0
- print(a / b)except IOError:
- print("catch exception")
- print('End')
運行結果
Start
Traceback (most recent calllast):
File"C:/Users/Kevin/PycharmProjects/PyDemo/p1/exception_demo.py", line 5,in
print(a / b)
ZeroDivisionError: division byzero
使用except可以帶多種異常類型,
try:
正常的操作
......................
except(Exception1, Exception2,...ExceptionN):
發生以上多個異常中的一個,執行這塊代碼
......................
try...except BaseExceptionas msg: 輸出異常信息.例如:
- print('Start')
- try:
- a =10
- b = 0
- print(a / b)except BaseException as msg:
- print(msg)print('End')
輸出:
Start
division by zero
End
try...except...finally
該語句的含義是無論是否發生異常都將執行最后finally中的代碼。示例代碼如下:
- print('Start')
- try:
- a =10
- b = 0
- print(a / b)except :
- print('exception')
- finally:
- print("finally")
- print('End')
輸出:
Start
exception
finally
End
拋出異常
raise語句允許程序員強制發生指定的異常。如果你需要確定是否引發了異常但不打算處理它時可以使用!例如:
- def exp_fuc():
- raise IOError
- exp_fuc()print('End')
運行結果
Traceback(most recent call last):
File"C:/Users/Kevin/PycharmProjects/PyDemo/p1/except_demo2.py", line 7,in
exp_fuc()
File"C:/Users/Kevin/PycharmProjects/PyDemo/p1/except_demo2.py", line 5,in exp_fuc
raise IOError
OSError
可以看到代碼拋出了IOError,由于沒有被捕獲,所以print('End')沒有被執行
自定義異常
程序可以通過創建新的異常類來命名它們自己的異常。異常通常應該直接或間接地從Exception類派生。
- def exp_fuc():
- raise IOError
- exp_fuc()print('End')
運行結果
Myexception: my error