溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python怎么使用異常處理機(jī)制

發(fā)布時(shí)間:2020-08-26 16:13:07 來(lái)源:億速云 閱讀:144 作者:Leah 欄目:編程語(yǔ)言

Python怎么使用異常處理機(jī)制?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

成功的異常處理應(yīng)該實(shí)現(xiàn)如下 4個(gè)目標(biāo):

使程序代碼混亂最小化。

捕獲并保留診斷信息。

通知合適的人員。

采用合適的方式結(jié)束異?;顒?dòng)。

下面介紹達(dá)到這些效果的基本準(zhǔn)則。

不要過(guò)度使用異常

不可否認(rèn),Python 的異常機(jī)制確實(shí)方便,但濫用異常機(jī)制也會(huì)帶來(lái)一些負(fù)面影響。過(guò)度使用異常主要表現(xiàn)在兩個(gè)方面:

把異常和普通錯(cuò)誤混淆在一起,不再編寫任何錯(cuò)誤處理代碼,而是以簡(jiǎn)單地引發(fā)異常來(lái)代苦所有的錯(cuò)誤處理。

使用異常處理來(lái)代替流程控制。

熟悉了異常使用方法后,程序員可能不再愿意編寫煩瑣的錯(cuò)誤處理代碼,而是簡(jiǎn)單地引發(fā)異常。實(shí)際上這樣做是不對(duì)的,對(duì)于完全己知的錯(cuò)誤和普通的錯(cuò)誤,應(yīng)該編寫處理這種錯(cuò)誤的代碼,增加程序的健壯性。只有對(duì)于外部的、不能確定和預(yù)知的運(yùn)行時(shí)錯(cuò)誤才使用異常。

對(duì)比前面五子棋游戲中,處理用戶輸入坐標(biāo)點(diǎn)己有棋子的兩種方式。如果用戶試圖下棋的坐標(biāo)點(diǎn)己有棋子:

#如果要下棋的點(diǎn)不為空
if board[int(y_str) - 1) [int(x_str) - 1] !="╋" :
    inputStr = input ("您輸入的坐標(biāo)點(diǎn)己有棋子了,請(qǐng)重新輸入\n")
    continue

上面這種處理方式檢測(cè)到用戶試圖下棋的坐標(biāo)點(diǎn)己經(jīng)有棋子,立即打印一條提示語(yǔ)句,并重新開(kāi)始下一次循環(huán)。這種處理方式簡(jiǎn)潔明了、邏輯清晰,程序的運(yùn)行效率也很好程序進(jìn)入 if 塊后,即結(jié)束了本次循環(huán)。

如果將上面的處理機(jī)制改為如下方式:

#如果要下棋的點(diǎn)不為空
if board[int(y_str) - 1) [int(x_str) - 1) != "╋":
    #引發(fā)默認(rèn)的RuntimeError 異常
    raise

上面這種處理方式?jīng)]有提供有效的錯(cuò)誤處理代碼,當(dāng)程序檢測(cè)到用戶試圖下棋的坐標(biāo)點(diǎn)己經(jīng)有棋子時(shí),并沒(méi)有提供相應(yīng)的處理,而是簡(jiǎn)單地引發(fā)一個(gè)異常。這種處理方式雖然簡(jiǎn)單,但 Python 解釋器接收到這個(gè)異常后,還需要進(jìn)入相應(yīng)的 except 塊來(lái)捕獲該異常,所以運(yùn)行效率要差一些。而且用戶下棋重復(fù)這個(gè)錯(cuò)誤完全是可預(yù)料的,所以程序完全可以針對(duì)該錯(cuò)誤提供相應(yīng)的處理,而不是引發(fā)異常。

另外,異常機(jī)制的效率比正常的流程控制效率差,所以不要使用異常處理來(lái)代替正常的程序流程控制。例如,對(duì)于如下代碼:

#定義一個(gè)字符串列表
my_list =["Hello", "Python", "Spring"]
#使用異常處理來(lái)遍歷arr數(shù)組的每個(gè)元素
try:
    i = 0
    while True:
    print (my_list [i])
    i += 1
except:
    pass

運(yùn)行上面程序確實(shí)可以實(shí)現(xiàn)遍歷 my_list 列表的功能,但這種寫法可讀性較差,而且運(yùn)行效率也不高。程序完全有能力避免產(chǎn)生 indexError 異常,程序“故意”制造這種異常,然后使用 except 塊去捕獲該異常,這是不應(yīng)該的。將程序改為如下形式肯定要好得多:

i = 0
while i < len(my_list):
    print(my_list[i])
    i += 1

注意,異常只應(yīng)該用于處理非正常的情況,不要使用異常處理來(lái)代替正常的流程控制。對(duì)于一些完全可預(yù)知,而且處理方式清楚的錯(cuò)誤,程序應(yīng)該提供相應(yīng)的錯(cuò)誤處理代碼,而不是將其籠統(tǒng)地稱為異常。

不要使用過(guò)于龐大的 try 塊

很多初學(xué)異常機(jī)制的讀者喜歡在 try 塊里放置大量的代碼,這看上去很“簡(jiǎn)單”,但這種“簡(jiǎn)單”只是一種假象,只是在編寫程序時(shí)看上去比較簡(jiǎn)單。但因?yàn)?try 塊里的代碼過(guò)于龐大,業(yè)務(wù)過(guò)于復(fù)雜,就會(huì)造成 try 塊中出現(xiàn)異常的可能性大大增加,從而導(dǎo)致分析異常原因的難度也大大增加。

而且當(dāng)時(shí)塊過(guò)于龐大時(shí),就難免在 try 塊后緊跟大量的 except 塊才可以針對(duì)不同的異常提供不同的處理邏輯。在同一個(gè) try 塊后緊跟大量的 except 塊則需要分析它們之間的邏輯關(guān)系,反而增加了編程復(fù)雜度。

正確的做法是,把大塊的 try 塊分割成多個(gè)可能出現(xiàn)異常的程序段落,并把它們放在單獨(dú)的 try 塊中,從而分別捕獲并處理異常。

不要忽略捕獲到的異常

不要忽略異常!既然己捕獲到異常,那么 except 塊理應(yīng)做些有用的事情,及處理并修復(fù)異常。except 塊整個(gè)為空,或者僅僅打印簡(jiǎn)單的異常信息都是不妥的!

except 塊為空就是假裝不知道甚至瞞天過(guò)海,這是最可怕的事情,程序出了錯(cuò)誤,所有人都看不到任何異常,但整個(gè)應(yīng)用可能已經(jīng)徹底壞了。僅在 except 塊里打印異常傳播信息稍微好一點(diǎn),但僅僅比空白多了幾行異常信息。通常建議對(duì)異常采取適當(dāng)措施,比如:

處理異常。對(duì)異常進(jìn)行合適的修復(fù),然后繞過(guò)異常發(fā)生的地方繼續(xù)運(yùn)行;或者用別的數(shù)據(jù)進(jìn)行計(jì)算,以代替期望的方法返回值;或者提示用戶重新操作……總之,程序應(yīng)該盡量修復(fù)異常,使程序能恢復(fù)運(yùn)行。

重新引發(fā)新異常。把在當(dāng)前運(yùn)行環(huán)境下能做的事情盡量做完,然后進(jìn)行異常轉(zhuǎn)譯,把異常包裝成當(dāng)前層的異常,重新傳給上層調(diào)用者。

在合適的層處理異常。如果當(dāng)前層不清楚如何處理異常,就不要在當(dāng)前層使用 except 語(yǔ)句來(lái)捕獲該異常,讓上層調(diào)用者來(lái)負(fù)責(zé)處理該異常。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI