8+Python程序設(shè)計+異常處理結(jié)構(gòu)與程序調(diào)試PPT演示_第1頁
8+Python程序設(shè)計+異常處理結(jié)構(gòu)與程序調(diào)試PPT演示_第2頁
8+Python程序設(shè)計+異常處理結(jié)構(gòu)與程序調(diào)試PPT演示_第3頁
8+Python程序設(shè)計+異常處理結(jié)構(gòu)與程序調(diào)試PPT演示_第4頁
8+Python程序設(shè)計+異常處理結(jié)構(gòu)與程序調(diào)試PPT演示_第5頁
已閱讀5頁,還剩25頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第8章

異常處理結(jié)構(gòu)與程序調(diào)試1異常(exception)簡單地說,異常是指程序運(yùn)行時引發(fā)的錯誤。引發(fā)錯誤的原因有很多,例如除零、下標(biāo)越界、文件不存在、網(wǎng)絡(luò)異常、類型錯誤、名字錯誤、字典鍵錯誤、磁盤空間不足,等等。如果這些錯誤得不到正確的處理將會導(dǎo)致程序終止運(yùn)行,而合理地使用異常處理結(jié)果可以使得程序更加健壯,具有更強(qiáng)的容錯性,不會因為用戶不小心的錯誤輸入或其他運(yùn)行時原因而造成程序終止。也可以使用異常處理結(jié)構(gòu)為用戶提供更加友好的提示。程序出現(xiàn)異?;蝈e誤之后是否能夠調(diào)試程序并快速定位和解決存在的問題也是程序員綜合水平和能力的重要體現(xiàn)方式之一。28.1什么是異常語法錯誤和邏輯錯誤不屬于異常,但有些語法錯誤往往會導(dǎo)致異常,例如由于大小寫拼寫錯誤而訪問不存在的對象。當(dāng)Python檢測到一個錯誤時,解釋器就會指出當(dāng)前流已無法繼續(xù)執(zhí)行下去,這時候就出現(xiàn)了異常。異常是指因為程序出錯而在正常控制流以外采取的行為。異常分為兩個階段:第一個階段是引起異常發(fā)生的錯誤;第二個階段是檢測并處理階段。不建議使用異常來代替常規(guī)的檢查,如if...else判斷。應(yīng)避免過多依賴于異常處理機(jī)制。當(dāng)程序出現(xiàn)錯誤,python會自動引發(fā)異常,也可以通過raise顯式地引發(fā)異常。38.2Python中的異常類下面列出了常用的異常類4拋出異常raise語句主動拋出異常定義自己的異常類時;或者需要拋出異常時。raise語法SomeException:必須是一個異常類,或異常類的實例;Args:傳遞給SomeException的參數(shù),必須是一個元組;Traceback:很少用,主要是用來提供一個traceback對象。raise

[SomeException[,args[,traceback]]

5自定義異常類下面的例子演示了自定義的異常類必須繼承Exception類:所有異常類的基類;class

MyError(Exception):

def

__init__(self,value):self.value=value

def

__str__(self):

returnrepr(self.value)>>>

try:

raiseMyError(2*2)exceptMyErrorase:

print('Myexceptionoccurred,value:',e.value)Myexceptionoccurred,value:

4>>>

raiseMyError('oops!')Traceback(mostrecentcalllast):File"<stdin>",line1,

in

?__main__.MyError:

'oops!'68.3Python中的異常處理結(jié)構(gòu)常見的異常處理結(jié)構(gòu)try.......except結(jié)構(gòu)try.......except.......else結(jié)構(gòu)帶有多個except的try結(jié)構(gòu)try.......except.......finally結(jié)構(gòu)78.3.1try.......except結(jié)構(gòu)這是最基本的處理結(jié)構(gòu);具有兩種形式。代碼處理形式一try:try_block#被監(jiān)控的代碼exceptException[,reason]:except_block#異常處理代碼

代碼處理形式二try:

...exceptBaseException,e:except_block優(yōu)勢:能夠處理所有的異常建議盡量顯式捕捉可能會出現(xiàn)的異常,并編寫具有針對性的代碼;最后一個except用來捕捉BaseException。8try.......except:示例1>>>

while

True:

try:x=int(input("Pleaseenteranumber:"))

break

exceptValueError:

print("Thatwasnovalidnumber.Tryagain...")Pleaseenteranumber:aThatwasnovalidnumber.Tryagain...Pleaseenteranumber:bThatwasnovalidnumber.Tryagain...Pleaseenteranumber:cThatwasnovalidnumber.Tryagain...Pleaseenteranumber:

109try.......except:示例2>>>

try:

raiseException('spam',

'eggs')exceptExceptionasinst:

print(type(inst))

#theexceptioninstance

print(inst.args)

#argumentsstoredin.args

print(inst)

#__str__allowsargstobeprinteddirectly,

#butmaybeoverriddeninexceptionsubclassesx,y=inst.args#unpackargs

print('x=',x)

print('y=',y)<class

'Exception'>('spam',

'eggs')('spam',

'eggs')x=spamy=eggs108.3.2try.......except.......else:示例1分析上述的代碼輸入錯誤:例如輸入了非數(shù)值,或者輸入的數(shù)值超出了正常的序號,會產(chǎn)生異常;執(zhí)行紅色print語句,并繼續(xù)循環(huán);其他的情況:輸出列表中正確的字符串,并且退出循環(huán)。a_list=

['China',

'America',

'England',

'France']while

True:

print('請輸入字符串的序號')n=int(input())

try:

print(a_list[n])

exceptIndexError:

print('列表元素的下標(biāo)越界,請重新輸入字符串的序號')

else:

break11try.......except.......else:示例2分析功能:讀取并輸出文件的內(nèi)容。在出現(xiàn)例外的情況下,執(zhí)行紅色的print語句后,結(jié)束程序的執(zhí)行;在沒有例外的情況下,執(zhí)行else塊的內(nèi)容。forarginsys.argv[1:]:

try:f=open(arg,

'r')

exceptIOError:

print('cannotopen',arg)

else:

print(arg,

'has',len(f.readlines()),

'lines')f.close()

128.3.3帶有多個except的try結(jié)構(gòu)功能:根據(jù)實際產(chǎn)生的例外,執(zhí)行其中的例外程序塊。try:try_block#被監(jiān)控的語句exceptException1:except_block_1#處理異常1的語句exceptException2:except_block_2#處理異常2的語句...13帶有多個except的try:示例1典型例子:除法。try:x=int(input('請輸入被除數(shù):'))y=int(input('請輸入除數(shù):'))z=float(x)

/yexceptZeroDivisionError:

print('除數(shù)不能為零')exceptTypeError:

print('被除數(shù)和除數(shù)應(yīng)為數(shù)值類型')exceptNameError:

print('變量不存在')else:

print(x,

'/',y,

'=',z)14帶有多個except的try:示例2當(dāng)有多個except塊而且處理相同時,可以使用元組的形式處理。importsystry:f=open('sample.txt')s=f.readline()i=int(s.strip())exceptOSErroraserr:

print("OSerror:{0}".format(err))exceptValueError:

print("Couldnotconvertdatatoaninteger.")except:

print("Unexpectederror:",sys.exc_info()[0])

raiseimportsystry:f=open('sample.txt')s=f.readline()i=int(s.strip())except(OSError,ValueError,RuntimeError,NameError):

pass

158.3.4try.......except.......finally結(jié)構(gòu)特點(diǎn)Finally中的語句總會執(zhí)行;可以用于清理工作,以便釋放資源。典型結(jié)構(gòu)如下try:try_block#被監(jiān)控的代碼except:except_block#例外處理程序塊finally:finally_block#無論如何都會執(zhí)行典型例子>>>

try:

3/0except:

print(3)finally:

print(5)3516try.......except.......finally:示例1典型例程:文件的讀取。try:f=open('sample.txt',

'r')line=f.readline(

)

print(line)finally:f.close()>>>

try:f=open('sample2.txt',

'r')line=f.readline()

print(line)finally:f.close()Traceback(mostrecentcalllast):File"<pyshell#17>",line6,

in

<module>f.close()NameError:name'f'

is

notdefined完美代碼?如果文件沒有創(chuàng)建,則在finally中會產(chǎn)生異常。17try.......except.......finally:示例2例外產(chǎn)生之后,需要有相應(yīng)的處理。如果沒有相應(yīng)的except處理塊,代碼的執(zhí)行順序會發(fā)生改變,直到找到相應(yīng)的except處理塊或者程序退出為止。>>>divide(2,

1)resultis

2.0executingfinallyclause>>>divide(2,

0)divisionbyzero!executingfinallyclause>>>divide("2",

"1")executingfinallyclauseTraceback(mostrecentcalllast):File"<stdin>",line1,

in

<module>File"<stdin>",line3,

individeTypeError:unsupportedoperandtype(s)

for

/:

'str'

and

'str'

def

divide(x,y):

try:result=x/y

exceptZeroDivisionError:

print("divisionbyzero!")

else:

print("resultis",result)

finally:

print("executingfinallyclause")18try.......except.......finally:示例3finally代碼中:返回值要慎重!def

demo_div(a,b):

try:

returna/b

except:

pass

finally:

return

-1

>>>demo_div(1,

0)-1>>>demo_div(1,

2)-1>>>demo_div(10,

2)

198.4斷言與上下文處理斷言與上下文處理兩種特殊的異常處理形式;形式上比通常的異常處理簡單;208.4.1斷言斷言語句的語法assertexpression[,reason]

當(dāng)判斷表達(dá)式expression為真時,什么都不做;如果表達(dá)式為假,則拋出異常。assert語句用途一般用于開發(fā)程序時對特定必須滿足的條件進(jìn)行驗證,僅當(dāng)__debug__為True時有效。當(dāng)Python腳本以-O選項編譯為字節(jié)碼文件時,assert語句將被移除以提高運(yùn)行速度。21斷言:示例1try:

assert

1

==

2

,

"1isnotequal2!"exceptAssertionErrorasreason:

print("%s:%s"%(reason.__class__.__name__,reason))AssertionError:1isnotequal2!22斷言:示例2例程中assert作用:調(diào)用函數(shù)使用的參數(shù)符合要求;不符合要求時:提示用戶存在的問題。def

RecursiveSum(n):

#precondition:n>=0

assert(n>=

0)

ifn==

0:

return

0

returnRecursiveSum(n-

1)

+n

#postcondition:returnedsumof1tondef

SumToN(n):

ifn<=

0:

raiseValueError("Nmustbegreaterthanorequalto0")

else:

returnRecursiveSum(n)>>>SumToN(10)55>>>SumToN('a')Traceback(mostrecentcalllast):File"<stdin>",line1,

in

<module>File"<stdin>",line2,

inSumToNTypeError:unorderabletypes:str()

<=int()>>>SumToN(-1)Traceback(mostrecentcalllast):File"<stdin>",line1,

in

<module>File"<stdin>",line3,

inSumToNValueError:Nmustbegreaterthanorequalto0238.4.2上下文管理使用with語句進(jìn)行上下文管理With語句的語法with語句的作用解決try…finally結(jié)構(gòu)中的資源釋放問題;提供了一種簡單的方法。with語句的實現(xiàn)依賴于python語言的magicmethod,需要實現(xiàn)__enter__()和__exit__()兩個方法:上下文管理協(xié)議;或者通過引用contextlib,并使用@contextlib.contextmanager方式實現(xiàn)。withcontext_expr[asobj]:with_blockobj=context_exprobj.__enter__()try:with_blockfinally:obj.__exit__()24with語句:示例1這是一個實用Timer類,可以用來記錄運(yùn)行時間;可以對照上一頁的內(nèi)容理解本類的內(nèi)容。importtimeclass

Timer(object):

def

__init__(self):

pass

def

__enter__(self):self.start=time.time()

def

__exit__(self,exception_type,exception_val,trace):

print("elapsed:",time.time()

-self.start)withTimer():

[iforiinrange(10000)]elapsed:1.744504928588867225with語句:示例2代碼和前面(1)中的代碼功能相同;通過使用@contextlib.contextmanager實現(xiàn)。importcontextlibimporttime

@contextlib.contextmanagerdef

time_print(task_name):t=time.time()

try:

yield

finally:

print(task_name,

"took",time.time()

-t,

"seconds.")withtime_print("processes"):

[ifor

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論