《Python程序設(shè)計(jì)》課件第九章-異常處理_第1頁
《Python程序設(shè)計(jì)》課件第九章-異常處理_第2頁
《Python程序設(shè)計(jì)》課件第九章-異常處理_第3頁
《Python程序設(shè)計(jì)》課件第九章-異常處理_第4頁
《Python程序設(shè)計(jì)》課件第九章-異常處理_第5頁
已閱讀5頁,還剩30頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論