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