版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第9章異常處理授課計(jì)劃內(nèi)置異常類型異常(exception)是指程序運(yùn)行時(shí)引發(fā)的錯(cuò)誤,引發(fā)錯(cuò)誤的原因很多,如除零、類型錯(cuò)誤、下標(biāo)越界、字典鍵錯(cuò)誤、文件不存在、磁盤空間不足、網(wǎng)絡(luò)異常等這些錯(cuò)誤如沒有得到適當(dāng)處理,將會(huì)導(dǎo)致程序運(yùn)行終止而合理地使用異常處理能夠讓程序在發(fā)生異常后盡可能地運(yùn)行下去,并為用戶提供更加友好的錯(cuò)誤提示信息Python內(nèi)置了60余個(gè)提前定義好的異常類型用戶可以使用它們處理普通應(yīng)用程序可能發(fā)生的大多數(shù)異常還可以使用面向?qū)ο蠹夹g(shù)從Python內(nèi)置的Exception類繼承定義自己的異常類型什么是異常Python事先將可能發(fā)生的錯(cuò)誤分門別類地加以整理,將其稱為異常當(dāng)特定的異常發(fā)生時(shí),用戶程序可以捕捉異常并進(jìn)行處理,也可以選擇忽視異常異常類型如果用戶程序?qū)Πl(fā)生的異常不做處理,Python默認(rèn)的處理方式是像上面的例子那樣終止程序執(zhí)行并顯示異常信息如果用戶提供處理異常的代碼,Python會(huì)在捕捉到異常后轉(zhuǎn)而執(zhí)行用戶的異常處理代碼,并在執(zhí)行完畢后繼續(xù)運(yùn)行原程序發(fā)生異常之后的部分異常類型實(shí)際上,Python定義的異常不只包括程序運(yùn)行時(shí)發(fā)生的錯(cuò)誤,一些事件的發(fā)生也以異常的形式向外報(bào)告例如,到達(dá)可迭代對(duì)象末尾會(huì)觸發(fā)StopIteration異常,用戶中斷執(zhí)行(如在交互環(huán)境中輸入Ctrl+C)會(huì)產(chǎn)生KeyboardInterrupt異常等異常類型Python內(nèi)置異常類的繼承層次Python事先將可能發(fā)生的錯(cuò)誤分門別類地加以整理,將其稱為異常當(dāng)特定的異常發(fā)生時(shí),用戶程序可以捕捉異常并進(jìn)行處理,也可以選擇忽視異常BaseException是一切異常類的基類,它有四個(gè)子類:Exception、GeneratorExit、KeyboardInterrupt和SystemExit其中的GeneratorExit、KeyboardInterrupt和SystemExit是與系統(tǒng)退出相關(guān)的異常,與一般的應(yīng)用程序關(guān)系不大Exception類包含各式各樣的異常子類,用戶編寫的應(yīng)用程序最常處理的就是這些類Python內(nèi)置異常類的繼承層次異常處理使用try…except語句捕捉并處理異常,將可能產(chǎn)生異常的代碼加上縮進(jìn)置于關(guān)鍵字try之下,待捕捉的異常類的名字置于關(guān)鍵字except之后,再加上縮進(jìn)后的用于處理異常的代碼,如下所示:相比Python默認(rèn)提供的異常處理機(jī)制(終止程序執(zhí)行,顯示異常信息),使用try…except語句捕獲異常并加以處理,程序在發(fā)生異常后還能繼續(xù)運(yùn)行下去,能夠提高程序的健壯性try…except語句try:
<statements>
#Runthismainactionfirstexcept
<name1>:
<statements>
#Runifname1israisedduringtryblockexcept
(<name2>,
<name3>):
<statements>
#Runifanyofname2orname3occurexcept
<name4>
as
<instance>:
<statements>
#Runifname4israised,andgetinstanceraisedexcept:
<statements>
#Runforall(other)exceptionsraise示例:運(yùn)行以上代碼,結(jié)果如下:try代碼塊中的語句1/0在運(yùn)行過程中產(chǎn)生的ZeroDivisionError異常被“exceptZeroDivisionError:”捕獲,緊接著執(zhí)行了except代碼塊中的用于處理異常的語句異常處理結(jié)束后,Python跳出try…except結(jié)構(gòu),繼續(xù)執(zhí)行之后的語句。位于try代碼塊內(nèi)1/0語句之后的“print('Thislinewillnotbeexecuted')”不會(huì)被執(zhí)行try…except語句try:
1
/
0
print('Thislinewillnotbeexecuted')except
ZeroDivisionError:
print('Catchanexception')print('Thislinewillbeexecutedasnormal')
CatchanexceptionThislinewillbeexecutedasnormal在except子句中,可以在異常名稱后面指定一個(gè)變量名該變量名和一個(gè)異常實(shí)例綁定,實(shí)例的參數(shù)存儲(chǔ)在args屬性中為了方便起見,異常類定義了自己的__str__()方法,因此可以直接顯示參數(shù)而無須引用args示例如下:try…except語句>>>
try:...
1
/
0...
except
ZeroDivisionError
aserr:...
print(type(err))...
print(err.args)...
print(err)...<class
'ZeroDivisionError'>('divisionbyzero',)divisionbyzero一個(gè)try語句可以附帶多個(gè)except子句,發(fā)生的異常與各個(gè)except子句中的異常類名進(jìn)行匹配,在第一次匹配成功后轉(zhuǎn)而執(zhí)行相應(yīng)except代碼塊中的內(nèi)容一個(gè)except子句也可以將多個(gè)異常類名組織成元組。只要匹配成功一次,就不會(huì)再嘗試匹配之后的except子句示例如下:try…except語句>>>
try:...
1
/
0...
except
NameError
aserr:...
print('Caughtanerror:{0}'.format(err))...
except
(TypeError,
RuntimeError,
ZeroDivisionError)
aserr:...
print('Caughtanerror:{0}'.format(err))...
except
ZeroDivisionError:...
print('Thislinewillnotbeexecuted')...Caughtanerror:divisionbyzero用在except子句中的異?;惪梢云ヅ渌淖宇惱?,下面的代碼通過繼承Python內(nèi)置的Exception類自定義了一個(gè)異常類B,然后依次定義了B的兩個(gè)子類C和D使用關(guān)鍵字raise后跟異常類實(shí)例對(duì)象的方式強(qiáng)制地產(chǎn)生異常,except子句捕獲異常后輸出異常的類型上例會(huì)依次輸出B、B、B。這是由于異?;怋被放在了第一個(gè)except子句中,從而“攔截”了所有的異常子類。交換語句exceptB和exceptD的位置,從而將異?;怋置于最后,就會(huì)輸出B、C、Dtry…except語句class
B(Exception):
passclass
C(B):
passclass
D(C):
passforclsin
(B,C,D):
try:
raisecls
raisecls()
exceptB:
print('B')
exceptC:
print('C')
exceptD:
print('D')注意:可以將except子句中的異常類名省去,這樣的空except子句將匹配一切異常但在實(shí)踐中應(yīng)謹(jǐn)慎使用這種方法,因?yàn)槠淙菀籽谏w真正的錯(cuò)誤此外,空except語句還會(huì)“攔截”系統(tǒng)退出事件類(Python內(nèi)置異常類繼承關(guān)系中的GeneratorExit、KeyboardInterrupt和SystemExit),這幾個(gè)異常事件一般不應(yīng)由用戶編寫的應(yīng)用程序處理因此,如果要一個(gè)作為“通配符”的except語句,應(yīng)該使用exceptException,它可以匹配除了GeneratorExit、KeyboardInterrupt和SystemExit之外的一切異常。try…except語句ry…except語句可以附帶一個(gè)else子句,其必須放在所有的except子句之后當(dāng)執(zhí)行完try代碼塊中的內(nèi)容而沒有產(chǎn)生任何異常時(shí)才會(huì)執(zhí)行else子句中的內(nèi)容下例在順利打開文件之后才執(zhí)行else子句中的內(nèi)容,輸出文件的行數(shù)try…except…else語句try:f=
open('filename.txt',
'r')except
OSError:
print('Cannotopenfile')else:
print('Filehas',
len(f.readlines()),
'lines')f.close()try語句還有另一個(gè)可選的finally子句如果在try代碼塊之后跟隨著finally子句,那么Python一定會(huì)執(zhí)行finally子句內(nèi)的代碼,而無論try代碼塊執(zhí)行時(shí)是否發(fā)生了異常根據(jù)異常是否發(fā)生以及finally之前是否有except子句,可以分為以下三種情況(1)如果try代碼塊在運(yùn)行過程中沒有異常發(fā)生,Python會(huì)在執(zhí)行完try代碼塊后繼續(xù)執(zhí)行finally中的內(nèi)容。示例如下:try…except…finally語句>>>
try:...
print('Weareallright')...
finally:...
print('Thislinewillalwaysbeexecuted')...WeareallrightThislinewillalwaysbeexecuted(2)如果try代碼塊在運(yùn)行過程中有異常發(fā)生,并且該異常被try之后的except子句捕獲,則Python會(huì)在執(zhí)行完except代碼塊后再執(zhí)行finally中的內(nèi)容。示例如下:try…except…finally語句>>>
try:...
raise
RuntimeError...
except
RuntimeError:...
print('Caughtanexception')...
finally:...
print('Thislinewillalwaysbeexecuted')...CaughtanexceptionThislinewillalwaysbeexecuted(3)如果try代碼塊在運(yùn)行過程中有異常發(fā)生,但該異常沒有被之后的except子句捕獲,則Python會(huì)先執(zhí)行finally中的內(nèi)容,接著把異常向上傳遞。在下面這個(gè)使用Python交互環(huán)境的例子中,“向上傳遞”意味著觸發(fā)Python默認(rèn)的異常處理機(jī)制,即顯示異常信息并終止程序運(yùn)行。try…except…finally語句>>>
try:...
raise
NameError...
except
RuntimeError:...
print('Caughtanexception')...
finally:...
print('Thislinewillalwaysbeexecuted')...ThislinewillalwaysbeexecutedTraceback(mostrecentcalllast):File"<stdin>",line2,
in
<module>NameError此外,如果在執(zhí)行try代碼塊的過程中遇到break、continue或return語句,則finally子句將在執(zhí)行break、continue或return語句之前被執(zhí)行。示例如下:如果finally子句中包含一個(gè)return語句,則返回值將來自finally子句的return語句的返回值,而非來自try子句的return語句的返回值。示例如下:try…except…finally語句>>>
while
True:...
try:...
break...
print('Nochancetoexecutethisline')...
finally:...
print('Thislinewillalwaysbeexecuted')...Thislinewillalwaysbeexecuted如果finally子句中包含一個(gè)return語句,則返回值將來自finally子句的return語句的返回值,而非來自try子句的return語句的返回值。示例如下:try…except…finally語句>>>
def
bool_return():...
try:...
return
True...
finally:...
return
False...>>>bool_return()False至此,將Python中與try…except相關(guān)的語法總結(jié)如下:try…except…else…finally語句try:
<statements>
#Runthismainactionfirstexcept
<name1>:
<statements>
#Runifname1israisedduringtryblockexcept
(<name2>,
<name3>):
<statements>
#Runifanyofname2orname3occurexcept
<name4>
as
<instance>:
<statements>
#Runifname4israised,andgettheinstanceraisedexcept:
<statements>
#Runforall(other)exceptionsraisedelse:
<statements>
#Runifnoexceptionisraisedduringtryblockfinally:
<statements>
#Willalwaysrun使用過raise語句能夠顯示地觸發(fā)異常。以下兩種方式效果相同,都會(huì)引發(fā)指定的異常類的一個(gè)實(shí)例,只是第一種形式通過調(diào)用沒有參數(shù)的構(gòu)造函數(shù)來隱式地創(chuàng)建實(shí)例:在創(chuàng)建異常類的實(shí)例對(duì)象時(shí),可以為其提供參數(shù),該參數(shù)一般是一個(gè)用于描述異常的字符串,此時(shí)必須使用括號(hào)。示例如下:raise語句>>>
raise
IndexError('theindexshouldstartfrom0')Traceback(mostrecentcalllast):File"<stdin>",line1,
in
<module>IndexError:theindexshouldstartfrom
0>>>
raise
IndexErrorTraceback(mostrecentcalllast):File"<stdin>",line1,
in
<module>IndexError>>>
raise
IndexError()Traceback(mostrecentcalllast):File"<stdin>",line1,
in
<module>IndexError僅使用關(guān)鍵字raise而不在其后附加異常名,就是重新引發(fā)當(dāng)前的異常如果在捕獲一個(gè)異常之后還希望該異常能繼續(xù)傳遞下去,可以使用單獨(dú)的raise語句raise語句importsystry:f=
open('filename.txt')s=f.readline()i=
int(s.strip())except
OSError
aserr:
print('OSerror:{0}'.format(err))except
ValueError:
print('Cannotconvertdatatoaninteger')except
Exception:
print("Unexpectederror:",sys.exc_info()[0])
raiseexcept
Exception:
print('Unexpectederror:',sys.exc_info()[0])
raise用戶自定義異常除了使用Python提供的內(nèi)置異常類外,用戶還可以通過繼承定義自己的異常類用戶自定義的異常類不應(yīng)繼承Python一切內(nèi)置異常的基類BaseException,而應(yīng)繼承Exception類可以選擇直接繼承Exception類,也可以繼承Exception類的子類這樣一來,在一條try…except語句的except子句中指明Exception,就可以捕獲除了系統(tǒng)退出事件之外的所有異常。自定義異常用戶自定義的異常類雖然可以執(zhí)行任何操作,但一般都刻意保持簡單,只提供一些屬性用于記錄與異常相關(guān)的信息在為一個(gè)應(yīng)用程序定義專用的異常類時(shí),通常的做法是先創(chuàng)建基類,再由該基類派生出不同的錯(cuò)誤條件下的異常子類自定義異常class
CustomError(Exception):
"""Baseclassforotheruser-definedexceptions"""
passclass
ValueTooSmallError(CustomError):
"""Raisedwhentheinputvalueistoosmall"""
passclass
ValueTooLargeError(CustomError):
"""Raisedwhentheinputvalueistoolarge"""
pass可以在except子句中通過基類名捕獲所有的用戶自定義異常類,這正是使用繼承組織用戶自定義異常的好處自定義異常>>>
importsys>>>>>>
forclsin
(CustomError,ValueTooSmallError,ValueTooLargeError):...
try:...
raisecls()...
exceptCustomError:...
print(sys.exc_info())...(<class
'__main__.CustomError'>,CustomError(),
<tracebackobjectat0x0000022FCFB83E40>)(<class
'__main__.ValueTooSmallError'>,ValueTooSmallError(),
<tracebackobjectat0x0000022FCFB83E40>)(<class
'__main__.ValueTooLargeError'>,ValueTooLargeError(),
<tracebackobjectat0x0000022FCFB83E40>)斷言斷言(assert)用于在程序中插入簡單的邏輯判斷,以供調(diào)試之用。其語法如下:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 職業(yè)病安全生產(chǎn)管理制度
- 葡萄酒生產(chǎn)車間管理制度
- 門診院感知識(shí)培訓(xùn)制度
- 安全生產(chǎn)重大隱患交辦制度
- 豆制品公司生產(chǎn)管理制度
- 煤礦生產(chǎn)設(shè)計(jì)管理制度匯編
- 調(diào)味品生產(chǎn)企業(yè)管理制度
- 粉碎場生產(chǎn)安全管理制度
- 電焊工員工安全生產(chǎn)責(zé)任制度
- 安全生產(chǎn)及消防培訓(xùn)制度
- 高三一模考后家長會(huì)課件
- 2022依愛消防E1-8402型消防控制室圖形顯示裝置安裝使用說明書
- 職業(yè)培訓(xùn)機(jī)構(gòu)五年發(fā)展策略
- 《小盒子大舞臺(tái)》參考課件
- 任捷臨床研究(基礎(chǔ)篇)
- 供應(yīng)鏈危機(jī)應(yīng)對(duì)預(yù)案
- DBJ41-T 263-2022 城市房屋建筑和市政基礎(chǔ)設(shè)施工程及道路揚(yáng)塵污染防治差異化評(píng)價(jià)標(biāo)準(zhǔn) 河南省工程建設(shè)標(biāo)準(zhǔn)(住建廳版)
- 砌筑工技能競賽理論考試題庫(含答案)
- 水工鋼結(jié)構(gòu)平面鋼閘門設(shè)計(jì)計(jì)算書
- JJG 291-2018溶解氧測定儀
- 《抗體偶聯(lián)藥物》課件
評(píng)論
0/150
提交評(píng)論