Python常見異常的處理方式淺析
一、引言
有一定 Python 編程經(jīng)驗(yàn)的人估計(jì)十有八九使用過異常,異常對于程序的健壯性是毋庸置疑的。
二、使用異常對數(shù)據(jù)進(jìn)行初始化
在某些條件下,需要進(jìn)行數(shù)據(jù)初始化,但數(shù)據(jù)不能提前確認(rèn),這個(gè)時(shí)候就可以結(jié)合異常的使用來判斷是否需要進(jìn)行初始化。下面的代碼中的函數(shù) listDataStatics 用于統(tǒng)計(jì)列表中每個(gè)元素的出現(xiàn)個(gè)數(shù),處理時(shí)循環(huán)遍歷列表,對列表中已經(jīng)存在的元素計(jì)數(shù)器加 1,否則如果是鍵值不存在異常則進(jìn)行數(shù)據(jù)初始化:
def listDataStatics(infList):
dataInf = {}
for l in infList:
try:
dataInf[l] += 1
except KeyError as e:
dataInf[l] =1
return dataInf當(dāng)然上述過程也可以用列表的 index 等方法來實(shí)現(xiàn),但個(gè)人認(rèn)為這種方式最簡單。
三、使用異常實(shí)現(xiàn)重處理
某些異常需要進(jìn)行重處理,如出現(xiàn)網(wǎng)絡(luò)連接斷開時(shí)需要在網(wǎng)絡(luò)正常后重新訪問網(wǎng)絡(luò),下面是一個(gè)案例。
import urllib,time
def getHtmlPage(url):
while True:
try:
req = urllib.request.Request(url=url)
text = urllib.request.urlopen(req).read().decode()
except ConnectionError:
print("ConnectionError:network has disconnected")
time.sleep(3)
continue
except Exception as e:
err = str(e)
if err.find('getaddrinfo failed')>=0:
print("getaddrinfo failed:network has disconnected")
time.sleep(3)
continue
else: return ''
else:return text
四、使用異常應(yīng)對多種潛在情況
在使用 Moviepy1.03 通過 VideoFileClip 執(zhí)行報(bào) UnicodeDecodeError 錯(cuò),發(fā)現(xiàn)是少數(shù)視頻有問題,從報(bào)錯(cuò)信息看是 Moviepy 的 ffmpeg_reader.py 模塊有個(gè)如下代碼:infos = error.decode(‘utf8’)解碼出現(xiàn)問題,將其改為:infos = error.decode(‘ANSI’)順利解決,但解決后用來加載其他視頻文件又報(bào)錯(cuò),后來將代碼改成如下方式:
try:
infos = error.decode('utf8')
except Exception as e:
infos = error.decode('ANSI')五、獲取異常詳細(xì)信息
Python 自己拋出的異常會(huì)有詳細(xì)的異常信息,包括異常類型、錯(cuò)誤內(nèi)容、程序代碼位置及相關(guān)函數(shù)調(diào)用棧信息,但異常捕獲后這些錯(cuò)誤信息默認(rèn)就消失了,為了實(shí)現(xiàn)提供與 Python 相同的異常信息,需要異常捕獲程序進(jìn)行處理:
通過類似except Exception as e捕獲異常后,打印 e 的內(nèi)容(也可打印 e.errno、e.strerror)可以提供異常的類型及異常的錯(cuò)誤信息說明;
采用 traceback 模塊的 print_exc 查看異常對應(yīng)程序代碼位置及相關(guān)函數(shù)調(diào)用棧信息發(fā)生異常時(shí),Python 保留引發(fā)異常程序的當(dāng)前狀態(tài),并可通過 traceback 跟蹤異常發(fā)生時(shí)與函數(shù)調(diào)用堆棧有關(guān)的信息。程序調(diào)用每個(gè)函數(shù)時(shí),Python 會(huì)在“函數(shù)調(diào)用堆棧”的起始處插入函數(shù)名。一旦異常被引發(fā),Python 會(huì)搜索異常處理程序,如果當(dāng)前函數(shù)中沒有異常處理程序,當(dāng)前函數(shù)會(huì)終止執(zhí)行,Python 會(huì)搜索當(dāng)前函數(shù)的調(diào)用函數(shù),并以此類推,直到發(fā)現(xiàn)匹配的異常處理程序,或者 Python 抵達(dá)主程序?yàn)橹埂_@一查找合適的異常處理程序的過程就稱為“堆棧輾轉(zhuǎn)開解”(StackUnwinding)。
下面代碼在訪問網(wǎng)站遇到異常時(shí),打印詳細(xì)的異常錯(cuò)誤信息及代碼位置:
import urllib,traceback
def getHtmlPage(url):
try:
req = urllib.request.Request(url=url)
text = urllib.request.urlopen(req).read().decode()
except Exception as e:
print(f"訪問網(wǎng)站獲取推薦文章失敗,當(dāng)前url={url},異常原因:\n{e}\n" + '\n' + traceback.format_exc() )
return ''
else:return text
六、人工觸發(fā)異常
除了程序自動(dòng)引發(fā)的異常外,也可以通過 raise 函數(shù)主動(dòng)拋出異常,一般用在程序主動(dòng)檢查發(fā)現(xiàn)錯(cuò)誤的情況,避免錯(cuò)誤擴(kuò)散。下面這段代碼檢查列表 infList 中的元素是否為列表,如果不是列表則拋出異常:
for row in infList:
if not isinstance(row,list):
raise ValueError("checkAndRepairListData實(shí)參不滿足第一個(gè)參數(shù)為二維列表的要求!\n"+traceback.format_exc())可以看到,使用 raise 拋出異常時(shí),需要提供異常類型和異常信息,并在此時(shí)也可以獲取程序的代碼位置及函數(shù)堆棧信息。
七、異常嵌套
異常允許嵌套,包括在一個(gè) try...except 語句的 try 和 except 之間嵌入另一個(gè) try...except 語句,也可以在異常處理語句、else、finally 子句中再嵌套 try...except 語句,在此就不舉例介紹了。
小結(jié)
本文介紹了 Python 異常用于數(shù)據(jù)初始化、業(yè)務(wù)重處理、多情況處理的三種應(yīng)用方式,以及獲取異常詳細(xì)信息、人工觸發(fā)異常及異常嵌套等與異常相關(guān)的知識
到此這篇關(guān)于Python常見異常的處理方式淺析的文章就介紹到這了,更多相關(guān)Python異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PyCharm連接遠(yuǎn)程服務(wù)器的超級詳細(xì)教程
Pycharm可以與服務(wù)器建立連接,把相應(yīng)的項(xiàng)目同步到服務(wù)器上,下面這篇文章主要給大家介紹了關(guān)于PyCharm連接遠(yuǎn)程服務(wù)器的超級詳細(xì)教程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12
Python利用物理引擎Pymunk編寫一個(gè)解壓小游戲
這篇文章主要為大家詳細(xì)介紹了Python如何利用物理引擎Pymunk編寫一個(gè)解壓小游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2023-01-01
Python 安裝 virturalenv 虛擬環(huán)境的教程詳解
這篇文章主要介紹了Python 安裝 virturalenv 虛擬環(huán)境的教程,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
django中send_mail功能實(shí)現(xiàn)詳解
這篇文章主要給大家介紹了關(guān)于django中send_mail功能實(shí)現(xiàn)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02
PyQt5之如何設(shè)置QWidget窗口背景圖片問題
這篇文章主要介紹了PyQt5之如何設(shè)置QWidget窗口背景圖片問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06

