Python自動化測試之異常處理機(jī)制實(shí)例詳解
一、前言
今天筆者還是想要講python中的基礎(chǔ),主要講解Python中異常介紹、捕獲、處理相關(guān)知識點(diǎn)內(nèi)容,只有學(xué)好了這些才能為后續(xù)自動化測試框架搭建及日常維護(hù)做鋪墊,廢話不多說我們直接進(jìn)入主題吧。
二、異常處理合集
2.1 異常處理講解
在正式介紹異常處理之前,需要先讓大家了解一個(gè)概念:編程是不可能存在完美的,總有考慮不到的情況,因?yàn)槿藷o完人,人類是有缺陷的,更何況編程是出自人類之手,在真實(shí)項(xiàng)目中不要相信任何人所說的:我的代碼是完美的、這個(gè)絕對不會有問題類似的話,要知道在編程的世界里,沒有絕對的可靠。
大家也應(yīng)該清楚了,只要是人所編寫的程序就一定會存在問題,程序不按照正常流程執(zhí)行,我們就稱之為異常,異常處理顧名思義就是解決這種異常的情況,能夠讓程序正常按照邏輯和流程執(zhí)行。
2.2 異常捕獲
當(dāng)一個(gè)程序執(zhí)行報(bào)錯時(shí)會終止運(yùn)行,我們進(jìn)行異常處理后再次運(yùn)行就不會再出現(xiàn)報(bào)錯,能夠捕獲到這個(gè)報(bào)錯讓程序順利運(yùn)行,這個(gè)異常處理的過程我們稱之為異常捕獲,讓我們先看一個(gè)例子:
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
age = int(age)
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
如上代碼所示,輸入的數(shù)據(jù)為18時(shí),能夠正常的進(jìn)行程序的邏輯計(jì)算,從而正常執(zhí)行代碼直至結(jié)束,但這樣的代碼真的沒有問題嗎?我們再看這個(gè)例子,當(dāng)輸入為abc英文字母時(shí),出現(xiàn)了ValueError的錯誤,字面的意思是告訴我們出現(xiàn)了數(shù)值錯誤,無法將字符串轉(zhuǎn)換為整型:
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
age = int(age)
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
如上圖所示,出現(xiàn)了ValueError報(bào)錯時(shí),我們就可以通過異常捕獲進(jìn)行處理,處理后的代碼為:
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
try:
age = int(age)
except:
print("您的年齡輸入非法,請重新運(yùn)行本程序")
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
如上圖所示,我們再次執(zhí)行該程序并輸入abc,程序仍然無法運(yùn)行,已經(jīng)不是剛剛的ValueError報(bào)錯了,現(xiàn)在的報(bào)錯是TypeError報(bào)錯。
2.3 異常捕獲原理
要解決上面的TypeError的報(bào)錯,我們先來了解下異常捕獲的原理,當(dāng)正式開始一個(gè)try語句后,Python會在當(dāng)前程序的上下文中作標(biāo)記,當(dāng)異常出現(xiàn)時(shí)返回標(biāo)記處,try子句先執(zhí)行,后續(xù)可能會發(fā)生的場景:
場景一: 如果執(zhí)行try語句時(shí)發(fā)生異常,Python跳回至try并執(zhí)行第一個(gè)匹配該異常的except子句,異常處理完畢,繼續(xù)執(zhí)行代碼。
場景二: 如果執(zhí)行try語句時(shí)發(fā)生異常,且沒有匹配的except子句,異常將被遞交到上層的try或是程序的最上層,到此結(jié)束程序,打印錯誤信息。
場景三: 如果在try子句執(zhí)行時(shí)沒有發(fā)生異常,Python將繼續(xù)執(zhí)行代碼語句。
當(dāng)我們了解了異常捕獲的原理后在來看下之前的TypeError報(bào)錯如何解決,字面意思類型錯誤,整型無法與字符串進(jìn)行比較,但實(shí)際上在此之前我們就已經(jīng)對變量age進(jìn)行了處理,但因?yàn)椴东@到了try的異常,執(zhí)行了第一個(gè)匹配try的except子句,而子句又代替異常的語句,故此這里的類型轉(zhuǎn)換就失效了,再次進(jìn)行程序的運(yùn)行就會出現(xiàn)類型錯誤,解決這個(gè)辦法也很簡單,只需要把判斷語句也放在try中。
當(dāng)判斷語句放到try中就稍微改變了一點(diǎn)點(diǎn),如果沒有捕獲異常,程序照常執(zhí)行,判斷會生效,如果捕獲到了異常,那么會直接跳轉(zhuǎn)到except執(zhí)行輸出,提示您的年齡非法,就不會在有判斷的邏輯,因此也不會在出現(xiàn)TypeError的錯誤了,順帶一提,這就是我們常見的開發(fā)Bug “買一送一” ,二次修改的代碼如下:
# 程序仍然有可優(yōu)化的地方,僅展示try.. except語句的使用方式
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
try:
age = int(age)
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
except:
print("您的年齡輸入非法,請重新運(yùn)行本程序")


2.4 特定異常捕獲
特定異常捕獲顧名思義就是針對某一個(gè)出現(xiàn)的特定異常進(jìn)行捕獲,例如我們所遇到的ValueError,如果你捕獲的是其他異常類型,那么在代碼執(zhí)行時(shí)碰到了ValueError仍然會出現(xiàn)報(bào)錯:
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
try:
age = int(age)
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
# 這里進(jìn)行捕獲的異常類型是IndexError,非ValueError,最后的結(jié)果仍然會報(bào)錯,因?yàn)闆]有成功捕獲
except IndexError:
print("您的年齡輸入非法,請重新運(yùn)行本程序")
當(dāng)捕獲的類型錯誤時(shí),仍然會彈出報(bào)錯終止程序運(yùn)行,好比一個(gè)人酒駕,那么就應(yīng)該由交警處理而不是民政局的人處理,因?yàn)槟遣皇撬穆氊?zé),異常捕獲還要講究對口,如下代碼所示,如果設(shè)置成ValueError就能夠成功進(jìn)行捕獲,就好比交警處理了酒駕一樣,完美解決:
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
try:
age = int(age)
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
except ValueError:
print("您的年齡輸入非法,請重新運(yùn)行本程序")
2.5 異常捕獲的處理
剛剛我們舉了一個(gè)例子,當(dāng)異常捕獲為IndexError時(shí),運(yùn)行程序后仍然會出現(xiàn)ValueError的錯誤,但我們不設(shè)置直接使用except時(shí)反而能直接捕獲,那我們還要設(shè)置它做什么呢?想必有部分同學(xué)心中已經(jīng)會產(chǎn)生這樣的疑問了。
except可以理解為萬能警察,萬能捕手,它可以捕獲所有的異常類型(極少數(shù)無法直接捕獲),而特定的異常捕獲只能捕獲特定出現(xiàn)的異常情況,我們之所以還要使用,是因?yàn)樗菍iT捕獲一種類型的,好比一個(gè)人有皮膚問題,那么肯定是掛皮膚科門診要比急診科的醫(yī)生要更加專業(yè),正所謂術(shù)業(yè)有專攻。
except因?yàn)槭侨f能捕手,所以它在抓獲異常后的處理方式是一樣的,好比感冒和心臟病發(fā)作兩種癥狀,都是同樣的對待方式顯然是不合理的,那么這個(gè)時(shí)候就會由特定的“醫(yī)生” (特定捕獲) 進(jìn)行對應(yīng)的處理方式。
目前常見的一些報(bào)錯有:ValueError、TypeError、IndexError等等,那么在整個(gè)自動化測試的過程中,勢必會遇到很多其他的報(bào)錯,當(dāng)我們不清楚其他報(bào)錯的情況下如何進(jìn)行異常捕獲呢?兩種方式,第一種是錯過一次就記得了,好比一開始進(jìn)行編程的小伙伴們,誰也不知道會遇到ValueError一樣,當(dāng)碰到過一次后,下一次就會特別注意這個(gè)事情,提前做一個(gè)捕獲,俗稱踩坑。那另外一種方式就是在末尾繼續(xù)添加except,萬能捕手我們也留著,這樣當(dāng)特定捕獲沒有捕獲到異常但程序出現(xiàn)了異常時(shí),except就會進(jìn)行捕獲:
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
try:
age = int(age)
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
# 這里會報(bào)錯ValueError,因?yàn)椴东@的類型是IndexError,很明顯無法進(jìn)行ValueError異常捕獲,那么我們可以在添加一個(gè)萬能捕手except來進(jìn)行捕獲
except IndexError:
print("您的年齡輸入非法,請重新運(yùn)行本程序")
# 在下面可以在進(jìn)行一個(gè)except的添加:
except:
print("萬能捕手在此,束手就擒吧!")
2.6 except、Exception與BaseException
except我們知道了是萬能捕手,但其實(shí)它的身份是Exception,Python默認(rèn)幫我們省略了,實(shí)際上它是這樣的:
except Exception:
print("萬能捕手在此,束手就擒吧!")except與except Exception完全等價(jià),日常的編寫時(shí)可加可不加,依據(jù)個(gè)人習(xí)慣和喜好決定即可。而BaseException是Exception的父類,作為子類的Exception無法截獲父類BaseException類型的錯誤。
BaseException: 包含所有built-in exceptions
Exception: 不包含所有的built-in exceptions,只包含built-in, non-system-exiting exceptions,像SystemExit類型的exception就不包含在其中。Python所有的錯誤都是從BaseException類派生的
2.7 finally用法
finally的作用是無論except是否成功捕獲到了對應(yīng)的異常,均需要執(zhí)行finally下的代碼:
"""
參考如下代碼:打開了love.txt這個(gè)文件,進(jìn)行了閱讀,又想寫入一點(diǎn)東西,但現(xiàn)在是只讀的模式,無法進(jìn)行內(nèi)容寫入,故此會報(bào)錯io.UnsupportedOperation
雖然沒有寫入成功,但是這個(gè)文件是成功讀取了的,那么在文件的章節(jié)中提到過,如果打開了一個(gè)文件要記得關(guān)閉,否則其他人無法使用
所以在finally這里我們就可以加上f.close(),代表著無論是否有捕捉到異常,最后我都要關(guān)閉這個(gè)文件,以確保其他人能夠正常使用該文件
"""
import io
try:
f = open("love.txt", encoding="utf-8", mode="r")
f.read()
f.write("隨便寫點(diǎn)~")
except io.UnsupportedOperation:
print("抓的就是你這個(gè)io.UnsupportedOperation報(bào)錯")
finally:
# finally的作用是無論except是否成功捕獲到了對應(yīng)的異常,均需要執(zhí)行finally下的代碼
f.close()2.8 異常信息的打印輸出
雖然我們能夠捕獲異常,但我們肯定要了解到底是什么異常,在捕獲到一個(gè)異常時(shí)我們可以進(jìn)行異常信息的打?。?/p>
print("------------------- 歡迎來到報(bào)名注冊系統(tǒng) -------------------")
age = (input("請輸入您的年齡:"))
try:
age = int(age)
if age < 18:
print("很遺憾,您暫時(shí)不滿足注冊條件")
else:
print("恭喜您符合注冊條件")
# 這里會報(bào)錯ValueError,捕獲的是IndexError,很明顯無法進(jìn)行異常捕獲,那么我們可以在添加一個(gè)萬能捕手except來進(jìn)行捕獲
except IndexError as error:
print("您的年齡輸入非法,請重新運(yùn)行本程序")
# 在這里加一個(gè)as,后面接一個(gè)變量,然后進(jìn)行變量打印即可,當(dāng)出現(xiàn)對應(yīng)的異常時(shí)就會打印對應(yīng)異常的信息
except Exception as error:
print("萬能捕手在此,束手就擒吧!", f"已捕獲異常:{error}")
剛剛有提到except與except Exception是等價(jià)的,但是如果想使用as必須要使用后者,這是語法規(guī)定:
# 正確用法,在捕獲類型后加as 變量
except Exception as error:
print("萬能捕手在此,束手就擒吧!", f"已捕獲異常:{error}")
# 錯誤的用法,不符合語法規(guī)則
except as error:
print("萬能捕手在此,束手就擒吧!", f"已捕獲異常:{error}")三、總結(jié)
到此這篇關(guān)于Python自動化測試之異常處理機(jī)制的文章就介紹到這了,更多相關(guān)Python異常處理機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 數(shù)據(jù)結(jié)構(gòu)之十大經(jīng)典排序算法一文通關(guān)
排序算法可以分為內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存2021-10-10
python+mysql實(shí)現(xiàn)學(xué)生信息查詢系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python+mysql實(shí)現(xiàn)學(xué)生信息查詢系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
Python面向?qū)ο蠡A(chǔ)入門之編碼細(xì)節(jié)與注意事項(xiàng)
這篇文章主要給大家介紹了關(guān)于Python面向?qū)ο蠡A(chǔ)入門之編碼細(xì)節(jié)與注意事項(xiàng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
學(xué)生如何免費(fèi)使用Pycharm專業(yè)版學(xué)生認(rèn)證教程
這篇文章主要介紹了學(xué)生如何免費(fèi)使用Pycharm專業(yè)版,學(xué)生認(rèn)證教程,有了這個(gè)教程在校期間就可以免費(fèi)使用Pycharm,簡直是學(xué)生黨的福音,快來一起看看吧2023-03-03
Python使用Gradio實(shí)現(xiàn)免費(fèi)的內(nèi)網(wǎng)穿透
內(nèi)網(wǎng)穿透是一種將內(nèi)部網(wǎng)絡(luò)服務(wù)暴露到公共網(wǎng)絡(luò)的技術(shù),可以讓外部用戶訪問內(nèi)部網(wǎng)絡(luò)上的服務(wù),本文將介紹如何使用Gradio實(shí)現(xiàn)免費(fèi)的內(nèi)網(wǎng)穿透,需要的可以參考下2024-03-03

