資訊內(nèi)容
讀懂Python的異常機(jī)制
前言:之前工作時(shí)用python完成一個(gè)利用串口發(fā)SCPI與單片機(jī)交互通信的命令行窗口,在實(shí)現(xiàn)功能的時(shí)候發(fā)現(xiàn)用python對(duì)數(shù)據(jù)結(jié)果無論是**終正確值的返回還是錯(cuò)誤值的返回都可以直接return給主界面。顯然直接return不同含義的數(shù)據(jù)是不行的,所以采用異常機(jī)制來處理錯(cuò)誤值的數(shù)據(jù)。因?yàn)橹皩?duì)異常這方面了解的比較少,在此查了點(diǎn)資料并整理個(gè)小筆記。KYa少兒編程網(wǎng)-https://www.pxcodes.com
KYa少兒編程網(wǎng)-https://www.pxcodes.com
文章目錄KYa少兒編程網(wǎng)-https://www.pxcodes.com
一、對(duì)異常的理解1、什么是異常2、錯(cuò)誤和異常的區(qū)別3、常見python異常種類二、python五大異常處理機(jī)制1、默認(rèn)異常處理機(jī)制2、try....except....處理機(jī)制3、try...except...finally.....處理機(jī)制4、assert斷言處理機(jī)制5、with...as處理機(jī)制三、python異常自定義1、異常自定義2、異常拋出raise3、異常捕獲四、異常使用注意事項(xiàng)1、不要太依賴異常機(jī)制2、不要在 try 塊中引入太多的代碼3、不要忽略捕獲到的異常總結(jié)KYa少兒編程網(wǎng)-https://www.pxcodes.com
(免費(fèi)學(xué)習(xí)推薦:python視頻教程)KYa少兒編程網(wǎng)-https://www.pxcodes.com
一、對(duì)異常的理解
KYa少兒編程網(wǎng)-https://www.pxcodes.com
1、什么是異常KYa少兒編程網(wǎng)-https://www.pxcodes.com
??異常即“與正常情況不同”,何為正常?正常便是解釋器在解釋代碼時(shí),我們所編寫的代碼符合解釋器定義的規(guī)則,即為正常,當(dāng)解釋器發(fā)現(xiàn)某段代碼符合語法但有可能出現(xiàn)不正常的情況時(shí),解釋器便會(huì)發(fā)出一個(gè)事件,中斷程序的正常執(zhí)行。這個(gè)中斷的信號(hào)便是一個(gè)異常信號(hào)。所以,總體解釋就是,在解釋器發(fā)現(xiàn)到程序出現(xiàn)錯(cuò)誤的時(shí)候,則會(huì)產(chǎn)生一個(gè)異常,若程序沒有處理,則會(huì)將該異常拋出,程序的運(yùn)行也隨之終止。我們可以在一個(gè)空白的.py文件中寫一句int(“m”),運(yùn)行后結(jié)果如下。
KYa少兒編程網(wǎng)-https://www.pxcodes.com
??這一串字體為解釋器拋出的一系列錯(cuò)誤信息,因?yàn)閕nt()傳入的參數(shù)只支持?jǐn)?shù)字字符串和數(shù)字,顯然‘m’不屬于數(shù)字字符串傳入?yún)?shù)錯(cuò)誤所以解釋器報(bào)“valueError”的錯(cuò)誤。KYa少兒編程網(wǎng)-https://www.pxcodes.com
2、錯(cuò)誤和異常的區(qū)別KYa少兒編程網(wǎng)-https://www.pxcodes.com
??對(duì)于python錯(cuò)誤的概述:它指的是代碼運(yùn)行前的語法或邏輯錯(cuò)誤。拿常規(guī)語法錯(cuò)誤來說,當(dāng)我們編寫的代碼過不了語法檢測(cè)時(shí),則會(huì)直接出現(xiàn)語法錯(cuò)誤,必須在程序執(zhí)行前就改正,不然寫的代碼將毫無意義,代碼是不運(yùn)行的,也無法捕獲得到。舉個(gè)例子,在.py文件輸入if a = 1 print(“hello”),輸出結(jié)果如下:KYa少兒編程網(wǎng)-https://www.pxcodes.com
Traceback (most recent call last): File "E:/Test_code/test.py",line 1 if a = 1 print("hello") ^SyntaxError: invalid syntax??函數(shù) print() 被檢查到有錯(cuò)誤,是它前面缺少了一個(gè)冒號(hào) : ,所以解析器會(huì)復(fù)現(xiàn)句法錯(cuò)誤的那行代碼,并用一個(gè)小“箭頭”指向行里檢測(cè)到的第一個(gè)錯(cuò)誤,所以我們可以直接找到對(duì)應(yīng)的位置修改其語法。當(dāng)然除了語法錯(cuò)誤,還有很多程序奔潰的錯(cuò)誤,如內(nèi)存溢出等,這類錯(cuò)誤往往比較隱蔽。
??相比于錯(cuò)誤,python異常主要在程序執(zhí)行過程中,程序遇見邏輯或算法問題,這時(shí)解釋器如果可以處理,則沒問題,如果處理不了,便直接終止程序,便將異常拋出,如第1小點(diǎn)的int(‘m’)例子,因?yàn)閰?shù)傳入錯(cuò)誤導(dǎo)致程序出錯(cuò)。這種因?yàn)檫壿嫯a(chǎn)生的異常五花八門,還好我們的解釋器都內(nèi)置好了各種異常的種類,讓我們知道是什么樣的異常出現(xiàn),好讓我們“對(duì)癥下藥”。
??這里注意一點(diǎn),上述語法錯(cuò)誤是可識(shí)別的錯(cuò)誤,所以解釋器也會(huì)默認(rèn)拋出一個(gè)SyntaxError異常信息反饋給程序員。所以本質(zhì)上大部分錯(cuò)誤都是可被輸出打印的,只是因?yàn)殄e(cuò)誤代碼不運(yùn)行,也就沒法處理,所以捕獲錯(cuò)誤的異常信息就變得沒意義。KYa少兒編程網(wǎng)-https://www.pxcodes.com
3、常見python異常種類KYa少兒編程網(wǎng)-https://www.pxcodes.com
??這里貼上我們?cè)趯懘a時(shí)**常見的異常類型,如果遇到其他種類的異常,當(dāng)然是選擇白度啦~KYa少兒編程網(wǎng)-https://www.pxcodes.com
異常名稱名稱解析BaseException所有異常的基類 SystemExit解釋器請(qǐng)求退出KeyboardInterrupt用戶中斷執(zhí)行(通常是輸入^C)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)算超出**大限制ZeropisionError除(或取模)零 (所有數(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)的方法SyntaxError Python語法錯(cuò)誤IndentationError縮進(jìn)錯(cuò)誤TabError Tab和空格混用SystemError一般的解釋器系統(tǒng)錯(cuò)誤TypeError對(duì)類型無效的操作ValueError傳入無效的參數(shù)UnicodeError Unicode相關(guān)的錯(cuò)誤UnicodeDecodeError Unicode解碼時(shí)的錯(cuò)誤UnicodeEncodeError Unicode編碼時(shí)錯(cuò)誤UnicodeTranslateError Unicode轉(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用戶代碼生成的警告二、python五大異常處理機(jī)制KYa少兒編程網(wǎng)-https://www.pxcodes.com
??我們明白了什么是異常后,那么發(fā)現(xiàn)異常后怎么處理,便是我們接下來要解決的問題。這里將處理異常的方式總結(jié)為五種。KYa少兒編程網(wǎng)-https://www.pxcodes.com
1、默認(rèn)異常處理機(jī)制KYa少兒編程網(wǎng)-https://www.pxcodes.com
??“默認(rèn)”則說明是解釋器默認(rèn)做出的行為,如果解釋器發(fā)現(xiàn)異常,并且我們沒有對(duì)異常進(jìn)行任何預(yù)防,那么程序在執(zhí)行過程中就會(huì)中斷程序,調(diào)用python默認(rèn)的異常處理器,并在終端輸出異常信息。剛才舉過的例子:int(“m”),便是解釋器因?yàn)榘l(fā)現(xiàn)參數(shù)傳入異常,這種異常解釋器“無能為力”,所以它**后中斷了程序,并將錯(cuò)誤信息打印輸出,告訴碼農(nóng)朋友們:你的程序有bug!!!KYa少兒編程網(wǎng)-https://www.pxcodes.com
2、try…except…處理機(jī)制KYa少兒編程網(wǎng)-https://www.pxcodes.com
??我們把可能發(fā)生錯(cuò)誤的語句放在try語句里,用except來處理異常。每一個(gè)try,都必須至少有一個(gè)或者多個(gè)except。舉一個(gè)**簡(jiǎn)單的例子如下,在try訪問number的第500個(gè)元素,很明顯數(shù)組越界訪問不了,這時(shí)候解釋器會(huì)發(fā)出異常信號(hào):IndexError,接著尋找后面是否有對(duì)應(yīng)的異常捕獲語句except ,如果有則執(zhí)行對(duì)應(yīng)的except語句,待except語句執(zhí)行完畢后,程序?qū)⒗^續(xù)往下執(zhí)行。如果沒有對(duì)應(yīng)的except語句,即用戶沒有處理對(duì)應(yīng)的異常,這時(shí)解釋器會(huì)直接中斷程序并將錯(cuò)誤信息打印輸出。KYa少兒編程網(wǎng)-https://www.pxcodes.com
number = 'hello'try: print(number[500]) #數(shù)組越界訪問except IndexError: print("下標(biāo)越界啦!")except NameError: print("未聲明對(duì)象!")print("繼續(xù)運(yùn)行...")輸出結(jié)果如下,因?yàn)榻忉屍靼l(fā)出異常信號(hào)是IndexError,所以執(zhí)行下標(biāo)越界語句。 KYa少兒編程網(wǎng)-https://www.pxcodes.com
下標(biāo)越界啦! 繼續(xù)運(yùn)行...??為了解鎖更多用法,我們?cè)賹⒗痈囊幌拢覀円廊辉趖ry訪問number的第500個(gè)元素,造成訪問越界錯(cuò)誤,這里的except用了as關(guān)鍵字可以獲得異常對(duì)象,這樣子便可獲得錯(cuò)誤的屬性值來輸出信息。KYa少兒編程網(wǎng)-https://www.pxcodes.com
number = 'hello'try: print(number[500]) #數(shù)組越界訪問except IndexError as e: print(e)except Exception as e: #萬能異常 print(e)except: #默認(rèn)處理所有異常 print("所有異常都可處理")print("繼續(xù)運(yùn)行...")輸出結(jié)果如下所示,會(huì)輸出系統(tǒng)自帶的提示錯(cuò)誤:string index out of range,相對(duì)于解釋器因?yàn)楫惓W约簰伋鰜淼囊欢鸭t色刺眼的字體,這種看起來舒服多了(能夠“運(yùn)籌帷幄”的異常才是好異常嘛哈哈哈)。另外這里用到“萬能異常”Exception,基本所有沒處理的異常都可以在此執(zhí)行。**后一個(gè)except表示,如果沒有指定異常,則默認(rèn)處理所有的異常。KYa少兒編程網(wǎng)-https://www.pxcodes.com
string index out of range繼續(xù)運(yùn)行...3、try…except…finally…處理機(jī)制KYa少兒編程網(wǎng)-https://www.pxcodes.com
??finally語句塊表示,無論異常發(fā)生與否,finally中的語句都要執(zhí)行完畢。也就是可以很霸氣的說,無論產(chǎn)生的異常是被except捕獲到處理了,還是沒被捕獲到解釋器將錯(cuò)誤輸出來了,都統(tǒng)統(tǒng)要執(zhí)行這個(gè)finally。還是原來簡(jiǎn)單的例子加上finally語句塊如下,代碼如下:KYa少兒編程網(wǎng)-https://www.pxcodes.com
number = 'hello'try: print(number[500]) #數(shù)組越界訪問,拋出IndexError異常except IndexError: print("下標(biāo)越界啦!")finally: print("finally!")print("繼續(xù)運(yùn)行...") #運(yùn)行結(jié)果如下,數(shù)據(jù)越界訪問異常被捕獲到后,先執(zhí)行except 語句塊,完畢后接著執(zhí)行了finally語句塊。因?yàn)楫惓1粓?zhí)行,所以后面代碼繼續(xù)運(yùn)行。KYa少兒編程網(wǎng)-https://www.pxcodes.com
下標(biāo)越界啦!finally! 繼續(xù)運(yùn)行...??對(duì)try語句塊進(jìn)行修改,打印abc變量值,因?yàn)閍bc變量沒定義,所以會(huì)出現(xiàn)不會(huì)被捕獲的NameError異常信號(hào),代碼如下所示:KYa少兒編程網(wǎng)-https://www.pxcodes.com
number = 'hello'try: print(abc) #變量未被定義,拋出NameError異常except IndexError: print("下標(biāo)越界啦!")finally: print("finally!")print("繼續(xù)運(yùn)行...") #不運(yùn)行結(jié)果如下,因?yàn)镹ameError異常信號(hào)沒法被處理,所以解釋器將程序中斷,并將錯(cuò)誤信息輸出,但這過程中依然會(huì)執(zhí)行finally語句塊的內(nèi)容。因?yàn)槌绦虮黄戎袛嗔耍院竺娲a不運(yùn)行。KYa少兒編程網(wǎng)-https://www.pxcodes.com
finally! #異常沒被捕獲,也執(zhí)行了finallyTraceback (most recent call last): File "E:/Test_code/test.py",line 3,in <module> print("abc")NameError: name 'abc' is not defined??理解到這里,相信:try…finally…這種機(jī)制應(yīng)該也不難理解了,因?yàn)槭÷粤薳xcept 捕獲異常機(jī)制,所以異常不可能被處理,解釋器會(huì)將程序中斷,并將錯(cuò)誤信息輸出,但finally語句塊的內(nèi)容依然會(huì)被執(zhí)行。例子代碼如下:KYa少兒編程網(wǎng)-https://www.pxcodes.com
number = 'hello'try: print(abc) #變量未被定義,拋出NameError異常finally: print("finally!")print("繼續(xù)運(yùn)行...")運(yùn)行結(jié)果:KYa少兒編程網(wǎng)-https://www.pxcodes.com
finally! #異常沒被捕獲,也執(zhí)行了finallyTraceback (most recent call last): File "E:/Test_code/test.py",line 3,in <module> print("abc")NameError: name 'abc' is not defined4、assert斷言處理機(jī)制KYa少兒編程網(wǎng)-https://www.pxcodes.com
??assert語句先判斷assert后面緊跟的語句是True還是False,如果是True則繼續(xù)往下執(zhí)行語句,如果是False則中斷程序,將錯(cuò)誤信息輸出。KYa少兒編程網(wǎng)-https://www.pxcodes.com
assert 1 == 1 #為True正常運(yùn)行assert 1 == 2 #為False,終止程序,錯(cuò)誤信息輸出5、with…as處理機(jī)制KYa少兒編程網(wǎng)-https://www.pxcodes.com
??with…as一般常用在文件處理上,我們平時(shí)在使用類似文件的流對(duì)象時(shí),使用完畢后要調(diào)用close方法關(guān)閉,很麻煩,這里with…as語句提供了一個(gè)非常方便且人性的替代方法,即使突發(fā)情況也能正常關(guān)閉文件。舉個(gè)例子代碼如下,open打開文件后將返回的文件流對(duì)象賦值給fd,然后在with語句塊中使用。KYa少兒編程網(wǎng)-https://www.pxcodes.com
with open('e:/test.txt','r') as fd: fd.read() print(abc) #變量未被定義,程序終止,錯(cuò)誤信息輸出print("繼續(xù)運(yùn)行...")??正常情況下,這里的with語句塊完畢之后,會(huì)自動(dòng)關(guān)閉文件。但如果with語句執(zhí)行中發(fā)生異常,如代碼中的變量未定義異常,則會(huì)采用默認(rèn)異常處理機(jī)制,程序終止,錯(cuò)誤信息輸出,后面代碼不被運(yùn)行,文件也會(huì)正常關(guān)閉。KYa少兒編程網(wǎng)-https://www.pxcodes.com
三、python異常自定義KYa少兒編程網(wǎng)-https://www.pxcodes.com
??說了這么多異常的使用,終于可以回到我前言所說的在實(shí)際項(xiàng)目中存在的問題,即錯(cuò)誤碼的返回和數(shù)值的返回是沖突的(因?yàn)殄e(cuò)誤碼也是數(shù)值),這時(shí)候便可以用異常的拋出和捕獲來完成錯(cuò)誤碼的傳遞,即try和except 。但系統(tǒng)發(fā)生異常時(shí)拋出的是系統(tǒng)本身定義好的異常類型,跟自己的錯(cuò)誤碼又有何關(guān)系?這就是我接下來要說的內(nèi)容:如何定義自己的異常并且能夠被except 所捕獲。KYa少兒編程網(wǎng)-https://www.pxcodes.com
1、異常自定義KYa少兒編程網(wǎng)-https://www.pxcodes.com
??實(shí)際開發(fā)中,有時(shí)候系統(tǒng)提供的異常類型往往都不能滿足開發(fā)的需求。這時(shí)候就要使用到異常的自定義啦,你可以通過創(chuàng)建一個(gè)新的異常類來擁有自己的異常。自己定義的異常類繼承自 Exception 類,可以直接繼承,或者間接繼承。栗子舉起來:KYa少兒編程網(wǎng)-https://www.pxcodes.com
class MyException(Exception): '''自定義的異常類''' def __init__(self, error_num): #異常類對(duì)象的初始化屬性 self.error_num = error_num def __str__(self): #返回異常類對(duì)象說明信息 err_info = ['超時(shí)錯(cuò)誤','接收錯(cuò)誤'] return err_info[self.error_num]??該類繼承自Exception 類,并且新類的名字為MyException,這跟前面我們一直在用的IndexError這個(gè)異常類一樣,都是繼承自Exception 類。__init__為構(gòu)造函數(shù),當(dāng)我們創(chuàng)建對(duì)象時(shí)便會(huì)自動(dòng)調(diào)用,__str__為對(duì)象說明信息函數(shù),當(dāng)使用print輸出對(duì)象的時(shí)候,只要自己定義了__str__方法,那么就會(huì)打印從在這個(gè)方法中return的數(shù)據(jù)。
??即print(MyException(0))時(shí),便可打印“超時(shí)錯(cuò)誤”這個(gè)字符串,print(MyException(1))時(shí),便可打印“接收錯(cuò)誤”這個(gè)字符串,心細(xì)的你應(yīng)該可以理解,MyException(x)為臨時(shí)對(duì)象(x是傳入錯(cuò)誤碼參數(shù),這里只定義了0和1),與a = MyException(x),a為對(duì)象一個(gè)樣子 。 這里有一個(gè)好玩的說法,在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法。KYa少兒編程網(wǎng)-https://www.pxcodes.com
2、異常拋出raiseKYa少兒編程網(wǎng)-https://www.pxcodes.com
??現(xiàn)在我們自己定義的錯(cuò)誤定義好了(上面的MyException),怎么能像IndexError一樣讓except捕獲到呢?于是乎raise關(guān)鍵字派上用場(chǎng)。我們?cè)诋惓C(jī)制中用try…except時(shí),一般都是將可能產(chǎn)生的錯(cuò)誤代碼放到try語句塊中,這時(shí)出現(xiàn)異常則系統(tǒng)便會(huì)自動(dòng)將其拋出,比如IndexError,這樣except就能捕獲到,所以我們只要將自定義的異常在需要的時(shí)候?qū)⑵鋻伋黾纯伞?br/> ??raise **的一個(gè)參數(shù)指定了要被拋出的異常。它必須是一個(gè)異常的實(shí)例或者是異常的類(也就是 Exception 的子類),那么我們剛剛定義的異常類就可以用啦,舉個(gè)簡(jiǎn)單例子:KYa少兒編程網(wǎng)-https://www.pxcodes.com
try: raise MyException(0) # 自己定義的錯(cuò)誤類,將錯(cuò)誤碼為0的錯(cuò)誤拋出except MyException as e: print(e) # 輸出的是__str__返回的內(nèi)容,即“超時(shí)錯(cuò)誤”??這里我直接將自己定義的錯(cuò)誤拋出,…as e就是把得到的錯(cuò)誤當(dāng)成對(duì)象e,這樣才可以訪問其屬性和方法。因?yàn)樽约憾x的錯(cuò)誤中可以支持多個(gè)錯(cuò)誤碼(本質(zhì)還是MyException這個(gè)錯(cuò)誤),所以便可實(shí)現(xiàn)傳入不同錯(cuò)誤碼就可打印不同錯(cuò)誤信息。KYa少兒編程網(wǎng)-https://www.pxcodes.com
3、異常捕獲KYa少兒編程網(wǎng)-https://www.pxcodes.com
??只要我們?cè)趖ry中將錯(cuò)誤raise出來,except就可以捕獲到(當(dāng)然,異常必須是Exception 子類才能被捕獲),將前面兩個(gè)例子整合起來,代碼如下:KYa少兒編程網(wǎng)-https://www.pxcodes.com
'''錯(cuò)誤碼:0代表超時(shí)錯(cuò)誤,1代表接收錯(cuò)誤'''class MyException(Exception): '''自定義的異常類''' def __init__(self, error_num): # 異常類對(duì)象的初始化屬性 self.error_num= error_num def __str__(self): # 返回異常類對(duì)象指定錯(cuò)誤碼的信息 err_info = ['超時(shí)錯(cuò)誤','接收錯(cuò)誤'] return err_info[self.error_num]def fun() raise MyException(1) # 拋出異常對(duì)象,傳入錯(cuò)誤碼1def demo_main(): try: fun() except MyException as ex: # 這里要使用MyException進(jìn)行捕獲,對(duì)象為ex print(ex) # 輸出的是__str__部分返回的內(nèi)容,即“接收錯(cuò)誤” print(ex.error_num) # 輸出的是__init__中定義的error_num,即1demo_main() #此處開始運(yùn)行??代碼從demo_main函數(shù)開始執(zhí)行,進(jìn)入try語句塊,語句塊中的fun()函數(shù)模擬代碼運(yùn)行失敗時(shí)raise 自定義的異常,except 正常接收后通過as 關(guān)鍵字得到異常對(duì)象,訪問該異常對(duì)象,便可正常輸出自定義的異常信息和自定義的錯(cuò)誤碼。KYa少兒編程網(wǎng)-https://www.pxcodes.com
四、異常使用注意事項(xiàng)KYa少兒編程網(wǎng)-https://www.pxcodes.com
此注意事項(xiàng)參考博文:異常機(jī)制使用細(xì)則.KYa少兒編程網(wǎng)-https://www.pxcodes.com
1、不要太依賴異常機(jī)制KYa少兒編程網(wǎng)-https://www.pxcodes.com
??python 的異常機(jī)制非常方便,對(duì)于信息的傳遞中十分好用(這里信息的傳遞主要有三種,參數(shù)傳遞,全局變量傳遞,以及異常機(jī)制傳遞),但濫用異常機(jī)制也會(huì)帶來一些負(fù)面影響。過度使用異常主要表現(xiàn)在兩個(gè)方面:①把異常和普通錯(cuò)誤混淆在一起,不再編寫任何錯(cuò)誤處理代碼,而是以簡(jiǎn)單地引發(fā)異常來代苦所有的錯(cuò)誤處理。②使用異常處理來代替流程控制。例子如下:KYa少兒編程網(wǎng)-https://www.pxcodes.com
buf = "hello"#例1:使用異常處理來遍歷arr數(shù)組的每個(gè)元素try: i = 0 while True: print (buf [i]) i += 1except: pass#例2:使用流程控制避免下標(biāo)訪問異常i = 0while i < len(buf ): print(buf [i]) i += 1??例1中假如循環(huán)過度便會(huì)下標(biāo)訪問異常,這時(shí)候把錯(cuò)誤拋出,再進(jìn)行一系列處理,顯然是不可取的,因?yàn)楫惓C(jī)制的效率比正常的流程控制效率差,顯然例2中簡(jiǎn)單的業(yè)務(wù)流程就可以避開這種錯(cuò)誤。所以不要熟悉了異常的使用方法后,遇到這種簡(jiǎn)單邏輯,便不管三七二十一引發(fā)異常后再進(jìn)行解決。對(duì)于完全己知的錯(cuò)誤和普通的錯(cuò)誤,應(yīng)該編寫處理這種錯(cuò)誤的代碼,增加程序的健壯性。只有對(duì)于外部的、不能確定和預(yù)知的運(yùn)行時(shí)錯(cuò)誤才使用異常。KYa少兒編程網(wǎng)-https://www.pxcodes.com
2、不要在 try 塊中引入太多的代碼KYa少兒編程網(wǎng)-https://www.pxcodes.com
??在 try 塊里放置大量的代碼,這看上去很“簡(jiǎn)單”,代碼框架很容易理解,但因?yàn)?try 塊里的代碼過于龐大,業(yè)務(wù)過于復(fù)雜,就會(huì)造成 try 塊中出現(xiàn)異常的可能性大大增加,從而導(dǎo)致分析異常原因的難度也大大增加。
??而且當(dāng)塊過于龐大時(shí),就難免在 try 塊后緊跟大量的 except 塊才可以針對(duì)不同的異常提供不同的處理邏輯。在同一個(gè) try 塊后緊跟大量的 except 塊則需要分析它們之間的邏輯關(guān)系,反而增加了編程復(fù)雜度。所以,可以把大塊的 try 塊分割成多個(gè)小塊,然后分別捕獲并處理異常。KYa少兒編程網(wǎng)-https://www.pxcodes.com
3、不要忽略捕獲到的異常KYa少兒編程網(wǎng)-https://www.pxcodes.com
??不要忽略異常!既然己捕獲到異常,那么 except 塊理應(yīng)做些有用的事情,及處理并修復(fù)異常。except 塊整個(gè)為空,或者僅僅打印簡(jiǎn)單的異常信息都是不妥的!具體的處理方式為:
①處理異常。對(duì)異常進(jìn)行合適的修復(fù),然后繞過異常發(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 語句來捕獲該異常,讓上層調(diào)用者來負(fù)責(zé)處理該異常。KYa少兒編程網(wǎng)-https://www.pxcodes.com
總結(jié)KYa少兒編程網(wǎng)-https://www.pxcodes.com
??本文從系統(tǒng)默認(rèn)的異常起手,說明了什么是異常并總結(jié)了系統(tǒng)常見的異常類,接著寫了怎么自定義異常,從異常的定義到拋出再到獲取完成自定義異常的定義和使用,**后再總結(jié)了python異常使用時(shí)的注意事項(xiàng)。KYa少兒編程網(wǎng)-https://www.pxcodes.com
相關(guān)免費(fèi)學(xué)習(xí)推薦:python教程(視頻)KYa少兒編程網(wǎng)-https://www.pxcodes.com
以上就是讀懂Python的異常機(jī)制的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注少兒編程網(wǎng)其它相關(guān)文章!KYa少兒編程網(wǎng)-https://www.pxcodes.com
- 上一篇
python畫圓運(yùn)用了什么函數(shù)
簡(jiǎn)介python畫圓運(yùn)用了matplotlb庫的figure()和Circle()函數(shù);其中,figure()函數(shù)用于確定畫布大小,而Circle()函數(shù)用于配置圓的相關(guān)信息,進(jìn)而畫圓。??本教程操作環(huán)境:windows7系統(tǒng)、Python3版、DellG3電腦。python畫圓代碼frommatplo
- 下一篇
Python作業(yè):直方圖、均衡化、高斯濾波
簡(jiǎn)介Python直方圖、均衡化、高斯濾波測(cè)試原圖直方圖基本原理matplotlib庫繪制直方圖RGB三通道直方圖直方圖均衡化基本原理PCV庫完成直方圖均衡化高斯濾波基本原理opencv高斯濾波實(shí)現(xiàn)(免費(fèi)學(xué)習(xí)推薦:python視頻教程)測(cè)試原圖直方圖基本原理什么是直方圖:圖像的直方圖描述圖像的灰度級(jí)和對(duì)應(yīng)
