python實用教程第九章異常處理課件_第1頁
python實用教程第九章異常處理課件_第2頁
python實用教程第九章異常處理課件_第3頁
python實用教程第九章異常處理課件_第4頁
python實用教程第九章異常處理課件_第5頁
已閱讀5頁,還剩22頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第九章 異常處理前面章節(jié)很多程序的執(zhí)行中,經(jīng)常會碰到程序執(zhí)行過程中沒有得到預(yù)期結(jié)果的情況。對于程序運行過程中出現(xiàn)的不正常,有時稱為錯誤,有時稱為異常,也有時說程序沒有按預(yù)期運行,從本章開始將有一個統(tǒng)一的稱謂異常。本章將帶領(lǐng)讀者學(xué)習(xí)如何處理各種異常,以及創(chuàng)建和自定義異常。Python快樂學(xué)習(xí)班的同學(xué)參觀完對象動物園后,由導(dǎo)游帶領(lǐng)來到了異常過山車入口。此處的異常過山車坐起來非常刺激,乘坐異常過山車的過程中,過山車隨時都可能停下來,有一些是正常的停止,也會有一些在未預(yù)知的情況下停止,但只要過山車上的乘客發(fā)揮自己的聰明才智,就有辦法讓停止的過山車動起來。聽起來很刺激吧,現(xiàn)在開始開啟異常過山車之旅。第1

2、頁,共27頁。9.1 異常定義在本節(jié)開始之前,先看看如下程序: print(hello,world)Traceback(most recent call last): File , line 1, in print(hello,world)NameError: name hello is not defined對于Python初學(xué)者,在Python的學(xué)習(xí)過程中,當編寫的代碼執(zhí)行時,經(jīng)常會遇到程序執(zhí)行報錯的問題,使程序不能得到預(yù)期結(jié)果,如NameError、SyntaxError、TypeError、ValueError等,這些都是異常。這節(jié)我們會專門介紹異常。第2頁,共27頁。異常是一個事件,

3、該事件會在程序執(zhí)行過程中發(fā)生,影響程序的正常執(zhí)行。一般情況下,在Python無法正常處理程序時就會發(fā)生異常。異常是Python的對象,表示一個錯誤。當Python腳本發(fā)生異常時,需要捕獲并處理所有異常,否則程序會終止執(zhí)行。就如乘坐過山車,有任何讓過山車在運行過程中停下的異常因素都需要排除,否則難以保證乘客的安全。在Python中,異常屬于類的實例,這些實例可以被引用,并且可以用很多種方法進行捕捉,使得異??梢杂靡恍┯押玫姆绞竭M行化解,而不是簡單粗暴的讓整個程序停止。第3頁,共27頁。9.2 異常化解出了異常怎么辦呢?就如乘坐的異常過山車,當在運行過程中停止時,乘客可以通過自己的才智讓過山車運行

4、起來。程序也一樣,作為程序開發(fā)人員,誰都不想讓自己寫出來的代碼有問題,但這幾乎是不可能的。好在編寫程序的前輩們經(jīng)過不斷積累與思考,創(chuàng)造了不少好方法處理程序中的異常, Python中,異常最簡單的化解方式是使用try語句。try語句的語法格式如下:try: #運行別的代碼except : #如果在try部份引發(fā)了異常第4頁,共27頁。try語句的工作原理是,開始一個try語句后,Python就在當前程序的上下文中做標記,當出現(xiàn)異常時就可以回到做標記的地方。如果當try后的語句執(zhí)行時發(fā)生異常,程序就跳回到try并執(zhí)行except子句,異常處理完畢,控制流就通過整個try語句(除非在處理異常時又引發(fā)

5、新的異常)。如果不想在發(fā)生異常時結(jié)束程序,只需在try語句塊中捕獲異常即可。def exp_exception(x,y): try: a=x/y print(a=, a) return a except Exception: print(程序出現(xiàn)異常,異常信息:被除數(shù)為0)exp_exception(2, 0)第5頁,共27頁。程序在執(zhí)行過程中,try語句塊中的語句在執(zhí)行時發(fā)生異常,程序最后執(zhí)行的是except子句。因為如果語句正常,應(yīng)該輸出“a=”的形式,但實際輸出的是except子句中的打印語句的內(nèi)容。在程序執(zhí)行過程中,如果沒有將異常化解,異常就會被“傳播”到調(diào)用的函數(shù)中。如果在調(diào)用的函數(shù)

6、中依然沒有化解異常,異常就會繼續(xù)“傳播”,直到程序的最頂層。在實際應(yīng)用中,經(jīng)常會遇到需要處理多個異常的情況,對于多個異常該怎么化解呢?Python支持在一個try/except語句中處理多個異常,語法格式如下:try: #運行別的代碼except : #如果在try部分引發(fā)了name1異常except ,: #如果引發(fā)了name2異常,獲得附加數(shù)據(jù)第6頁,共27頁。try語句按照如下方式工作:首先執(zhí)行try子句(在關(guān)鍵字try和關(guān)鍵字except之間的語句);如果try子句執(zhí)行沒有發(fā)生異常,忽略except子句,try子句執(zhí)行后結(jié)束;如果在執(zhí)行try子句的過程中發(fā)生異常,try子句余下的部分就

7、會被忽略;如果異常的類型和except之后的名稱相符,對應(yīng)的except子句就會被執(zhí)行,最后執(zhí)行try語句之后的代碼。如果拋出的異常沒有與任何except匹配,那這個異常就會傳遞到上層的try語句中。一個try語句可能包含多個except子句,分別處理不同的異常,但最多只有一個分支會被執(zhí)行。處理程序只針對對應(yīng)try子句中的異常進行處理,而不會處理其他異常語句中的異常。第7頁,共27頁。9.3 拋出異常Python使用raise語句拋出一個指定的異常。我們可以使用一個類(應(yīng)該是Exception的子類)或者實例參數(shù)調(diào)用raise語句來引發(fā)異常。使用類時,程序會自動創(chuàng)建實例。如果你只想知道這是否拋

8、出了一個異常,并不想去處理它,那使用一個簡單的raise語句就可以再次把它拋出。如下示例: try: raise NameError(This is NameError)except NameError: print(An exception happened!) #后面不加raiseAn exception happened! #若不加raise,輸出對應(yīng)字符就結(jié)束第8頁,共27頁。 try: raise NameError(This is NameError)except NameError: print(An exception happened!) raise #最后加一個raiseA

9、n exception happened!Traceback(most recent call last): File , line 2, in NameError: This is NameError在實際應(yīng)用過程中,可以借助raise語句得到更詳盡的異常信息。第9頁,共27頁。面碰到的如NameError、SyntaxError、TypeError、ValueError這些異常類稱為內(nèi)建異常類。在Python中,內(nèi)建的異常類有很多,可以使用dir函數(shù)列出異常類的內(nèi)容(有興趣可以嘗試看看),并且都可以用在raise語句中,用法如raise NameError這般使用。下表描述了一些重要的內(nèi)建

10、異常類。異常名稱描述Exception常規(guī)錯誤的基類AttributeError對象沒有這個屬性IOError輸入/輸出操作失敗IndexError序列中沒有此索引(index)KeyError映射中沒有這個鍵NameError未聲明/初始化對象 (沒有屬性)SyntaxErrorPython 語法錯誤SystemError一般的解釋器系統(tǒng)錯誤ValueError傳入無效的參數(shù)第10頁,共27頁。9.4 一個塊捕捉多個異常上一節(jié)我們講述的是一個try語句對應(yīng)多個except子句,假若需要一個try對應(yīng)一個except子句,同時捕捉到一個以上的異常。看如下示例:def model_excepti

11、on(x,y): try: b=name a=x/y except(ZeroDivisionError, NameError, TypeError): print(one of ZeroDivisionError or NameError or TypeError happened)model_exception(2,0)如果需要一個塊捕捉多個類型異常,可以將他們作為元組列出。第11頁,共27頁。程序輸出結(jié)果如下:one of ZeroDivisionError or NameError or TypeError happened由輸出結(jié)果可以看到,在一個try對應(yīng)一個except子句時,若將

12、多個異常放置于一個元組中,能做到捕獲一個以上的異常。使用這種方式時,只要遇到的異常類型是元組中的任意一個,都會進入異常流程。這么做有什么好處呢?假如希望多個except子句輸出同樣的信息,就沒有必要使一個try語句對應(yīng)多個except語句,將多個except的異常類放到一個except的元組中即可。第12頁,共27頁。9.5 異常對象捕捉如果希望在except子句中訪問異常對象本身,也就是看到一個異常對象真正的異常信息,而不是打印出自己定義的異常信息,可以使用 as e的形式,稱為捕捉對象。示例如下(model_exception_1.py):def model_exception(x,y):

13、 try: b=name a=x/y except(ZeroDivisionError, NameError, TypeError) as e: print(e)model_exception(2,0)第13頁,共27頁??慈缦率纠╩odel_exception_2.py):def model_exception(x,y): try: a=x/yb=name except(ZeroDivisionError, NameError, TypeError) as e: print(e)model_exception(2,) 在該示例中,調(diào)用函數(shù)時有一個實參傳入的是空值。輸出結(jié)果如下:unsupp

14、orted operand type(s) for /: int and str 第14頁,共27頁。在實際編碼過程中,即使程序能處理好幾種類型的異常,但有一些異常還是會從我們手掌中溜走。上面示例中的異常就逃過了try/except語句的檢查,對于這種情況根本無法預(yù)測會發(fā)生什么,也無法提前做任何準備。在這種情況下,與其使用不是捕捉異常的try/except語句隱藏異常,不如讓程序立即崩潰。對于這樣的異常,該用什么方式來化解?示例如下(model_exception_3.py):def model_exception(x,y): try: b=name a=x/y except: print(E

15、rror happened)model_exception(2,)第15頁,共27頁。可以在except子句中忽略所有異常類,從而讓程序輸出自己定義的異常信息。這里只是給出了一種可參考的解決方式。從實用性方面來講,不建議這么做,因為這樣捕捉異常非常危險,會隱藏所有沒有預(yù)先想到的錯誤。建議在實際應(yīng)用中,使用拋出異常的方式處理,或者對異常對象e進行一些檢查。第16頁,共27頁。9.6 豐富的else子句異常為我們提供了try.except.else的語句來實現(xiàn)該功能,其語法如下:try: #運行別的代碼except : #如果在try部份引發(fā)了異常1except ,: #如果引發(fā)了異常2,獲得附加

16、的數(shù)據(jù)else: #如果沒有異常發(fā)生第17頁,共27頁。如果在try子句執(zhí)行時沒有發(fā)生異常,python將執(zhí)行else語句后的語句(如果有else的話)。使用else子句比把所有的語句都放在 try 子句里面要好,這樣可以避免一些意想不到的而except又沒有捕獲的異常。如下示例(model_exception_4.py):def model_exception(x, y): try: a=x/y except: print(發(fā)生異常,走的是except邏輯。) else: print(沒有發(fā)生異常,走的是else邏輯。)model_exception(2, 1) #model_excepti

17、on函數(shù)調(diào)用當程序沒有發(fā)生異常時,通過添加一個else子句來做一些事情是很有用的,它可以幫助我們更好的判斷程序的執(zhí)行情況。第18頁,共27頁。9.7 自定義異常盡管內(nèi)建異常類包括了大部分異常,也可以滿足很多要求,但有一些情況還是需要創(chuàng)建自己的異常類才能處理。比如,若需要精確知道問題的根源,就需要使用自定義異常來精確定位問題。可以通過創(chuàng)建一個新exception類擁有自己的異常。異常應(yīng)該繼承自Exception類,可以直接繼承,也可以間接繼承。錯誤就是類,捕獲一個錯誤就是捕獲該類的一個實例,因此錯誤并不是憑空產(chǎn)生的,而是由一些不合理的部分導(dǎo)致的。Python的內(nèi)置函數(shù)會拋出很多類型的錯誤,自己編

18、寫的函數(shù)也可以拋出錯誤。如果要拋出錯誤,那么可以根據(jù)需要定義一個錯誤的類,選擇好繼承關(guān)系,然后用raise語句拋出一個錯誤的實例。代碼示例(my_error.py)第19頁,共27頁。9.8 try-finally語句Python中的finally子句需要和try子句一起使用,組成try/finally的語句形式。try/finally語句無論發(fā)生異常與否都將執(zhí)行finally后的代碼。示例如下(use_finally.py):def use_finally(x,y): try: a=x/y finally: print(No matter what happened,I will show

19、in front of you)use_finally(2,0)第20頁,共27頁。其實在Python中,不管try子句中是否發(fā)生異常,finally子句都會執(zhí)行。這里有一個疑問,雖然執(zhí)行了finally子句,但是最后仍然有異常拋出,是否可以使用except截獲異常呢?可以使用except來截獲異常。try、except、else和finally可以組合使用,但放置的順序規(guī)則是:else在except之后,finally在except和else之后。第21頁,共27頁。9.9 函數(shù)中的異常如果異常在函數(shù)內(nèi)引發(fā)而不被處理,就會傳播至函數(shù)調(diào)用的地方。如果異常在函數(shù)調(diào)用的地方也沒有被處理,就會繼續(xù)傳

20、播,一直到達主程序。如果在主程序中也沒有做異常處理,異常就會被Python解釋器捕獲,輸出一個錯誤信息,然后退出程序。示例如下(division_fun.py):def division_fun(x, y): return x / int(y)def exp_fun(x, y): return division_fun(x, y) * 10第22頁,共27頁。def main(x,y): exp_fun(x, y)main(2,0)在Python中,異常信息是以堆棧的形式被拋出的,因而是從下往上查看的。所謂堆棧,就是最先被發(fā)現(xiàn)的異常信息最后被輸出(就像子彈入彈夾和出彈夾一樣),也被稱為先進后出(First In Last Out,F(xiàn)ILO)。第23頁,共27頁。9.10 活學(xué)活用正常數(shù)異常數(shù)對給定的數(shù)組,數(shù)組中的前后兩個數(shù)相除,若被除數(shù)為0,則認為是異常數(shù),需要通過自定義異常打印出異常信息,并將該異常數(shù)加入異常數(shù)組中;若被除數(shù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論