yhon函數(shù)設(shè)計(jì)與異常_第1頁
yhon函數(shù)設(shè)計(jì)與異常_第2頁
yhon函數(shù)設(shè)計(jì)與異常_第3頁
yhon函數(shù)設(shè)計(jì)與異常_第4頁
yhon函數(shù)設(shè)計(jì)與異常_第5頁
已閱讀5頁,還剩57頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

Python函數(shù)設(shè)計(jì)和異常匯報(bào)人:付紅玉匯報(bào)時(shí)間:2018年5月一函數(shù)設(shè)計(jì)與使用1“”Python函數(shù)將可能需要反復(fù)執(zhí)行的代碼封裝為函數(shù),并在需要執(zhí)行該段代碼功能的地方進(jìn)行調(diào)用,不僅可以實(shí)現(xiàn)代碼的復(fù)用,更重要的是可以保證代碼的一致性,只需要修改該函數(shù)代碼則所有調(diào)用位置均得到體現(xiàn)。在編寫函數(shù)時(shí),有很多原則需要參考和遵守:1、不要在同一個(gè)函數(shù)中執(zhí)行太多的功能,盡量只讓其完成一個(gè)高度相關(guān)且大小合適的功能,以提高模塊的內(nèi)聚性。2、盡量減少不同函數(shù)之間的隱式耦合,例如減少全局變量的使用,使得函數(shù)之間僅通過調(diào)用和參數(shù)傳遞來顯式體現(xiàn)其相互關(guān)系。2函數(shù)定義

函數(shù)定義語法:def函數(shù)名([參數(shù)列表]):

'''注釋'''

函數(shù)體函數(shù)形參不需要聲明類型,也不需要指定函數(shù)返回值類型即使該函數(shù)不需要接收任何參數(shù),也必須保留一對空的圓括號括號后面的冒號必不可少函數(shù)體相對于def關(guān)鍵字必須保持一定的空格縮進(jìn)Python允許嵌套定義函數(shù)注意事項(xiàng)√√√√√3函數(shù)定義格式生成斐波那契數(shù)列的函數(shù)定義和調(diào)用:調(diào)用函數(shù)1000是實(shí)參n是形參deffib(n):a,b=1,1whilea<n:print(a,end='')a,b=b,a+bprint()fib(1000)定義頭函數(shù)體4函數(shù)的注釋在定義函數(shù)時(shí),開頭部分的注釋并不是必需的,但如果為函數(shù)的定義加上注釋的話,可以為用戶提供友好的提示.5函數(shù)對象的增加、刪除Python是一種高級動態(tài)編程語言,變量類型是隨時(shí)可以改變的。Python中的函數(shù)和自定義對象的成員也是可以隨時(shí)發(fā)生改變的,可以為函數(shù)和自定義對象動態(tài)增加新成員。>>>deffunc():print(func.x)#查看func的成員>>>func()#現(xiàn)在函數(shù)func還沒有成員x,出錯(cuò)AttributeError:'function'objecthasnoattribute'x‘>>>func.x=3#動態(tài)為函數(shù)增加新成員>>>func()3>>>delfunc.x#刪除成員>>>func()#刪除之后不可訪問AttributeError:'function'objecthasnoattribute'x‘6函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用是函數(shù)調(diào)用的一種情況,函數(shù)調(diào)用自己,自己再調(diào)用自己,自己再調(diào)用自己,…,當(dāng)某個(gè)條件得到滿足的時(shí)候,就不再調(diào)用了,然后再一層一層地返回知道該函數(shù)第一次調(diào)用的位置需要用棧來存儲該函數(shù)離開的位置,棧比較小,如果遞歸調(diào)用很深,則導(dǎo)致棧崩潰7尾遞歸尾遞歸是指:在函數(shù)返回的時(shí)候,調(diào)用自身本身,并且,return語句不能包含表達(dá)式。這樣,編譯器或者解釋器就可以把尾遞歸做優(yōu)化,使遞歸本身無論調(diào)用多少次,都只占用一個(gè)棧幀,不會出現(xiàn)棧溢出的情況。8遞歸實(shí)現(xiàn)n的階乘:deffact(n):ifn==1:return1returnn*fact(n-1)deffact(n):returnfact_iter(n,1)deffact_iter(num,product):ifnum==1:returnproductreturnfact_iter(num-1,num*product)改成尾遞歸returnfact_iter(num-1,num*product)僅返回遞歸函數(shù)本身num-1和num*product在函數(shù)調(diào)用前就會被計(jì)算,不影響函數(shù)調(diào)用遺憾的是:大多數(shù)編程語言沒有針對尾遞歸做優(yōu)化,Python解釋器也沒有做優(yōu)化,所以,即使把上面的fact(n)函數(shù)改成尾遞歸方式,也會導(dǎo)致棧溢出010203在Python中,定義函數(shù)時(shí)不需要聲明函數(shù)的返回值類型,而是使用return語句結(jié)束函數(shù)的執(zhí)行的同時(shí)返回任意類型的值,函數(shù)返回值類型與return語句返回表達(dá)式的類型一致。如果函數(shù)沒有return語句或者執(zhí)行了不返回任何值的return語句,Python將認(rèn)為該函數(shù)以returnNone結(jié)束,即返回空值函數(shù)基本語法9不論return語句出現(xiàn)在函數(shù)的什么位置,一旦得到執(zhí)行將直接結(jié)束函數(shù)的執(zhí)行。函數(shù)參數(shù)不不得不說的的幾件事((一)1)在定義函數(shù)數(shù)時(shí),對參數(shù)個(gè)個(gè)數(shù)并沒有有限制,如如果有多個(gè)個(gè)形參,則需要使用用逗號進(jìn)行行分隔.下下面的函數(shù)數(shù)用來接收收2個(gè)參數(shù),,并輸出其中中的最大值值:defprintMax(a,b):ifa>b:pirnt(a,'isthemax')else:print(b,'isthemax')2)對于絕大多多數(shù)情況下下,在函數(shù)內(nèi)內(nèi)部直接修修改形參的的值不會影影響實(shí)參:>>>defaddOne(a):print(a)#輸出原變量量a的值a+=1#這條語句會會得到一個(gè)個(gè)新的變量量aprint(a)>>>a=3>>>addOne(a)34>>>a310函數(shù)參數(shù)不不得不說的的幾件事((二)在有些情況況下,可以以通過特殊殊的方式在在函數(shù)內(nèi)部部修改實(shí)參參的值。>>>defmodify(v):#修改列表元素值值v[0]=v[0]+1>>>a=[2]>>>modify(a)>>>a[3]>>>defmodify(v,item):#為列表增加元素v.append(item)>>>a=[2]>>>modify(a,3)>>>a[2,3]>>>defmodify(d):#修改字典元素值或?yàn)闉樽值湓黾釉豥['age']=38>>>a={'name':'Dong','age':37,'sex':'Male'}>>>a{'age':37,'name':'Dong','sex':'Male'}>>>modify(a)>>>a{'age':38,'name':'Dong','sex':'Male'}11函數(shù)參數(shù)不不得不說的的幾件事((三)默認(rèn)值參數(shù)數(shù)在調(diào)用帶有有默認(rèn)值參參數(shù)的函數(shù)數(shù)時(shí),可以以不用為設(shè)設(shè)置了默認(rèn)認(rèn)值的形參參進(jìn)行傳值值,此時(shí)函函數(shù)將會直直接使用函函數(shù)定義時(shí)時(shí)設(shè)置的默默認(rèn)值,也也可以通過過顯式賦值值來替換其其默認(rèn)值。def函函數(shù)名(………,形參參名=默認(rèn)認(rèn)值):函數(shù)體可以使用“函數(shù)名.__defaults__”隨時(shí)查看函函數(shù)所有默默認(rèn)值參數(shù)數(shù)的當(dāng)前值值,其返回值為為一個(gè)元組,其中的元元素依次表表示每個(gè)默默認(rèn)值參數(shù)數(shù)的當(dāng)前值值。>>>defsay(message,times=1):print((message+'')*times)>>>say.__defaults__(1,)注意:函數(shù)參數(shù)的的默認(rèn)值是是在定義函函數(shù)時(shí)確定定的12函數(shù)參數(shù)不不得不說的的幾件事((四)(2)關(guān)鍵參參數(shù)通過關(guān)鍵參參數(shù)可以按按參數(shù)名字字傳遞值,,實(shí)參順序可可以和形參參順序不一一致,但不影響響參數(shù)值的的傳遞結(jié)果果,避免了了用戶需要要牢記參數(shù)數(shù)位置和順順序的麻煩煩,使得函函數(shù)的調(diào)用用和參數(shù)傳傳遞更加靈靈活方便。。>>>defdemo(a,b,c=5):print(a,b,c)>>>demo(c=8,a=9,b=0)90813函數(shù)參數(shù)不不得不說的的幾件事((五)(3)可變變長度參數(shù)數(shù)可變長度參參數(shù)在定義義函數(shù)時(shí)主主要有兩種種形式:*parameter和**parameter,前者者用來接收收任意多個(gè)個(gè)實(shí)參并將將其放在一一個(gè)元組中,后者接接收類似于于關(guān)鍵參數(shù)數(shù)一樣顯式式賦值形式式的多個(gè)實(shí)實(shí)參并將其其放入字典中。第一種形形式可變變長度參參數(shù)的用用法,無無論調(diào)用用該函數(shù)數(shù)時(shí)傳遞遞了多少少實(shí)參,,一律將將其放入入元組中中:>>>defdemo(*p):print(p)>>>demo(1,2,3,4,5,6,7)(1,2,3,4,5,6,7)第二種形式可可變長度度參數(shù)的的用法:>>>defdemo(**p):foriteminp.items():print(item)>>>demo(x=1,y=2,z=3)('y',2)('x',1)('z',3)14函數(shù)參數(shù)數(shù)不得不不說的幾幾件事((六)傳遞參數(shù)數(shù)時(shí)的序序列解包包>>>defdemo(a,b,c):print(a+b+c)>>>seq=[1,2,3]>>>demo(*seq)6>>>tup=(1,2,3)>>>demo(*tup)6>>>dic={1:'a',2:'b',3:'c'}>>>demo(*dic)6>>>Set={1,2,3}>>>demo(*Set)6>>>demo(*dic.values())abc15Key作為實(shí)參參函數(shù)參數(shù)數(shù)不得不不說的幾幾件事((七)注意:調(diào)用函數(shù)數(shù)時(shí)如果果對實(shí)參參使用一一個(gè)星號號*進(jìn)行行序列解解包,這這么這些些解包后后的實(shí)參參將會被被當(dāng)做普普通位置置參數(shù)對對待,并并且會在在關(guān)鍵參參數(shù)和使使用兩個(gè)個(gè)星號**進(jìn)行行序列解解包的參參數(shù)之前前進(jìn)行處處理。>>>defdemo(a,b,c):#定義函數(shù)數(shù)print(a,b,c)>>>demo(a=1,*(2,3))#序列解包包相當(dāng)于于位置參參數(shù),優(yōu)優(yōu)先處理理Traceback(mostrecentcalllast):File"<pyshell#26>",line1,in<module>demo(a=1,*(2,3))TypeError:demo()gotmultiplevaluesforargument'a'>>>demo(c=1,*(2,3))231>>>demo(**{'a':1,'b':2},*(3,))#序列解包包不能在在關(guān)鍵參參數(shù)解包包之后SyntaxError:iterableargumentunpackingfollowskeywordargumentunpacking>>>demo(*(3,),**{'c':1,'b':2})32116參數(shù)檢查查調(diào)用函數(shù)數(shù)時(shí),如如果參數(shù)數(shù)個(gè)數(shù)不不對,Python解釋器會會自動檢檢查出來來,并拋拋出TypeError:17defmy_abs(x):ifx>=0:returnxelse:return-x>>>my_abs(1,2)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:my_abs()takes1positionalargumentbut2weregiven如果參數(shù)類型型不對,,Python解釋器就就無法幫幫我們檢檢查??匆幌孪耺y_abs和內(nèi)置函函數(shù)abs的差別::>>>my_abs('A')Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"<stdin>",line2,inmy_absTypeError:unorderabletypes:str()>=int()>>>abs('A')Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:badoperandtypeforabs():'str'參數(shù)檢查查我們修改改一下my_abs的定義,,對參數(shù)數(shù)類型做做檢查,,只允許許整數(shù)和和浮點(diǎn)數(shù)數(shù)類型的的參數(shù)。。數(shù)據(jù)類類型檢查查可以用用內(nèi)置函函數(shù)isinstance()實(shí)現(xiàn):18defmy_abs(x):ifnotisinstance(x,(int,float)):raiseTypeError('badoperandtype')ifx>=0:returnxelse:return-x>>>my_abs('A')Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"<stdin>",line3,inmy_absTypeError:badoperandtype變量的作作用域1、變量起作用的的代碼范范圍稱為為變量的的作用域域,不同同作用域域內(nèi)變量量名可以以相同,,互不影響2、在函數(shù)內(nèi)部部定義的的普通變變量只在在函數(shù)內(nèi)內(nèi)部起作作用,稱稱為局部變量量。當(dāng)函數(shù)數(shù)執(zhí)行結(jié)結(jié)束后,,局部變變量自動動刪除,,不再可可以使用3、局部變量量的引用比比全局變變量速度度快,應(yīng)應(yīng)優(yōu)先考考慮使用用1、一個(gè)變變量已在函數(shù)數(shù)外定義義,如果在在函數(shù)內(nèi)內(nèi)需要為為這個(gè)變變量賦值值,并要要將這個(gè)個(gè)賦值結(jié)結(jié)果反映映到函數(shù)數(shù)外,可可以在函函數(shù)內(nèi)使使用global將其聲明為全局變變量。2、如果一一個(gè)變量量在函數(shù)外外沒有定定義,在函數(shù)內(nèi)內(nèi)部也可可以直接接將一個(gè)個(gè)變量定定義為全全局變量量,該函數(shù)執(zhí)行行后,將增加加一個(gè)新的全全局變量。全局變量可以以通過關(guān)鍵字字global來定義。這分分為兩種情況況:19>>>defdemo():globalxx=3y=4print(x,y)>>>x=5>>>demo()34>>>x3>>>yNameError:name'y'isnotdefined>>>delx>>>xNameError:name'x'isnotdefined>>>demo()34>>>x3>>>yNameError:name'y'isnotdefined變量的作用域域——例子20如果局部變量量與全局變量量具有相同的的名字,那么么該局部變量會在在自己的作用用域內(nèi)隱藏同同名的全局變變量。>>>defdemo():x=3#創(chuàng)建了局部部變量,并自自動隱藏了同同名的全局變量print(x)>>>x=5>>>demo()3>>>x#函數(shù)執(zhí)行不影影響外面全局局變量的值5變量的作用域域——例子21如果需要在同同一個(gè)程序的的不同模塊之之間共享全局局變量的話,,可以編寫一一個(gè)專門的模模塊來實(shí)現(xiàn)這這一目的。例如,假設(shè)在模塊塊A.py中中有如下變量量定義:global_variable=0而在模塊B.py中包含以以下用來設(shè)置置全局變量的的語句:importAA.global_variable=1在模模塊塊C.py中中有有以以下下語語句句來來訪訪問問全全局局變變量量的的值值::importAprint(A.global_variable)變量量的的作作用用域域———例子子22lambda表達(dá)達(dá)式式可可以以用用來來聲聲明明匿名名函函數(shù)數(shù),也也就就是是沒沒有有函函數(shù)數(shù)名名字字的的臨臨時(shí)時(shí)使使用用的的小小函函數(shù)數(shù),,尤尤其其適適合合需需要要一一個(gè)個(gè)函函數(shù)數(shù)作作為為另另一一個(gè)個(gè)函函數(shù)數(shù)參參數(shù)數(shù)的的場場合合。。也也可可以以定義義匿名名函函數(shù)數(shù)。lambda表達(dá)達(dá)式式只可可以以包包含含一一個(gè)個(gè)表表達(dá)達(dá)式式,該該表表達(dá)達(dá)式式的的計(jì)計(jì)算算結(jié)結(jié)果果可可以以看看作作是是函函數(shù)數(shù)的的返返回回值值,,不不允允許許包包含含復(fù)復(fù)合合語語句句,,但但在在表表達(dá)達(dá)式式中中可可以以調(diào)調(diào)用用其其他他函函數(shù)數(shù)。。Lambda表達(dá)達(dá)式式格式式::>>>f=lambdax,y,z:x+y+z#可以以給給lambda表達(dá)達(dá)式式起起名名字字>>>f(1,2,3)#像函函數(shù)數(shù)一一樣樣調(diào)調(diào)用用6>>>g=lambdax,y=2,z=3:x+y+z#參數(shù)默認(rèn)值值>>>g(1)6>>>g(2,z=4,y=5)#關(guān)鍵參數(shù)1123>>>L=[(lambdax:x**2),(lambdax:x**3),(lambdax:x**4)]>>>print(L[0](2),L[1](2),L[2](2))4816>>>D={'f1':(lambda:2+3),'f2':(lambda:2*3),'f3':(lambda:2**3)}>>>print(D['f1'](),D['f2'](),D['f3']())568>>>L=[1,2,3,4,5]>>>print(list(map(lambdax:x+10,L)))#模擬向量運(yùn)運(yùn)算[11,12,13,14,15]>>>L[1,2,3,4,5]Lambda表達(dá)式24>>>data=list(range(20))#創(chuàng)建列表>>>data[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]>>>importrandom>>>random.shuffle(data)#打亂順序>>>data[4,3,11,13,12,15,9,2,10,6,19,18,14,8,0,7,5,17,1,16]>>>data.sort(key=lambdax:x)#和不指定規(guī)規(guī)則效果一一樣>>>data[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]>>>data.sort(key=lambdax:len(str(x)))#按轉(zhuǎn)換成字字符串以后后的長度排排序>>>data[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]>>>data.sort(key=lambdax:len(str(x)),reverse=True)#降序排序>>>data[10,11,12,13,14,15,16,17,18,19,0,1,2,3,4,5,6,7,8,9]Lambda表達(dá)式25函數(shù)可以返返回多個(gè)值值嗎?答案是肯定定的。比如在游戲戲中經(jīng)常需需要從一個(gè)個(gè)點(diǎn)移動到到另一個(gè)點(diǎn)點(diǎn),給出坐坐標(biāo)、位移移和角度,,就可以計(jì)計(jì)算出新的的坐標(biāo):importmathdefmove(x,y,step,angle=0):nx=x+step*math.cos(angle)ny=y-step*math.sin(angle)returnnx,ny函數(shù)返回多個(gè)值(一)26importmathdefmove(x,y,step,angle=0):nx=x+step*math.cos(angle)ny=y-step*math.sin(angle)returnnx,ny27>>>x,y=move(100,100,60,math.pi/6)>>>print(x,y)151.9615242270663270.0但其實(shí)這只只是一種假假象,Python函數(shù)返回的的仍然是單單一值。>>>r=move(100,100,60,math.pi/6)>>>print(r)(151.96152422706632,70.0)原來返回值是一一個(gè)tuple!多個(gè)變量可以以同時(shí)接收收一個(gè)tuple,按位置賦賦給對應(yīng)的的值,所以以,Python的函數(shù)返回回多值其實(shí)實(shí)就是返回回一個(gè)tuple函數(shù)返回多個(gè)值(二)例1編寫函數(shù),,接收包含含20個(gè)整整數(shù)的列表表lst和和一個(gè)整數(shù)數(shù)k作為參參數(shù),返回回新列表。。處理規(guī)則則為:將列列表lst中下標(biāo)k之前的元元素逆序,,下標(biāo)k之之后的元素素逆序,然然后將整個(gè)個(gè)列表lst中的所所有元素逆逆序。>>>defdemo(lst,k):x=lst[:k]x.reverse()y=lst[k:]y.reverse()r=x+yreturnlist(reversed(r))>>>lst=list(range(1,21))>>>print(lst)[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]>>>print(demo(lst,5))[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4,5]案例精選(一)28例2編寫函數(shù),,接收一個(gè)個(gè)正偶數(shù)為為參數(shù),輸輸出兩個(gè)素素?cái)?shù),并且且這兩個(gè)素素?cái)?shù)之和等等于原來的的正偶數(shù)。。如果存在在多組符合合條件的素素?cái)?shù),則全全部輸出。。>>>importmath>>>defIsPrime(n):m=int(math.sqrt(n))+1foriinrange(2,m):ifn%i==0:returnFalsereturnTrue>>>defdemo(n):ifisinstance(n,int)andn>0andn%2==0:foriinrange(3,int(n/2)+1):ifi%2==1andIsPrime(i)andIsPrime(n-i):print(i,'+',n-i,'=',n)>>>demo(60)7+53=6013+47=6017+43=6019+41=6023+37=6029+31=60案例精選(二)29例3編寫函數(shù),接收兩個(gè)個(gè)正整數(shù)作作為參數(shù),,返回一個(gè)個(gè)元組,其其中第一個(gè)個(gè)元素為最最大公約數(shù)數(shù),第二個(gè)個(gè)元素為最最小公倍數(shù)數(shù)。>>>defdemo(m,n):ifm>n:m,n=n,mp=m*nwhilem!=0:r=n%mn=mm=rreturn(n,int(p/n))>>>print(demo(20,30))(10,60)案例精選(三)30函數(shù)設(shè)計(jì)與與使用小結(jié)結(jié)1、定義函數(shù)時(shí),需需要確定函數(shù)名和參數(shù)個(gè)數(shù)2、如果有必要,可可以先對參參數(shù)的數(shù)據(jù)類型做檢查3、函數(shù)體內(nèi)部可以以用return隨時(shí)返回函函數(shù)結(jié)果4、函數(shù)執(zhí)行完畢也也沒有return語句時(shí),自自動returnNone5、函數(shù)可以同時(shí)返回多個(gè)值值,但其實(shí)就就是一個(gè)tuple31Python異常處理結(jié)結(jié)構(gòu)32“”小故事歐洲阿麗亞亞娜5型火箭經(jīng)過過近十年研研發(fā),1996年首次發(fā)射射失敗,火火箭和箭上上衛(wèi)星全毀毀,造成巨巨大經(jīng)濟(jì)損損失。事故故起因是新新火箭直接接繼承了4型火箭“久久經(jīng)考驗(yàn)””的控制系系統(tǒng),但5型火箭加速速度大造成成傳感器讀讀數(shù)大,導(dǎo)導(dǎo)致一次從從浮點(diǎn)數(shù)到到整數(shù)的數(shù)數(shù)值轉(zhuǎn)換溢溢出。慣性性導(dǎo)航系統(tǒng)統(tǒng)失效后飛飛行狀態(tài)失失控,控制制系統(tǒng)關(guān)閉閉了火箭的的狀態(tài)調(diào)節(jié)節(jié)系統(tǒng),安安全系統(tǒng)最最后引爆火火箭自毀。。33箭載軟件出出錯(cuò)的原因因是,沒有有達(dá)到軟件件容錯(cuò)的目目標(biāo)01異常的基礎(chǔ)礎(chǔ)知識34“”異常概述簡單地說,,異常是指指程序運(yùn)行行時(shí)引發(fā)的的錯(cuò)誤,引引發(fā)錯(cuò)誤的的原因有很很多,例如如除零、下標(biāo)越界、、文件不存存在、網(wǎng)絡(luò)絡(luò)異常、類類型錯(cuò)誤、、名字錯(cuò)誤誤、字典鍵鍵錯(cuò)誤、磁磁盤空間不不足,等等。如果這些錯(cuò)錯(cuò)誤得不到到正確的處處理,將會會導(dǎo)致程序序終止運(yùn)行行,而合理理地使用異異常處理結(jié)結(jié)果,可以以使得程序序更加健壯壯,具有有更強(qiáng)的容容錯(cuò)性,不不會因?yàn)橛糜脩舨恍⌒男牡腻e(cuò)誤輸輸入或其他他運(yùn)行時(shí)原原因而造成成程序中止止。35基本概念Concept01020304語法錯(cuò)誤和邏輯錯(cuò)誤不屬于異常,但有些語法錯(cuò)誤往往會導(dǎo)致異常,例如由于大小寫拼寫錯(cuò)誤而訪問不存在的對象異常是指因?yàn)槌绦虺鲥e(cuò)而在正常控制流以外采取的行為,當(dāng)python檢測到一個(gè)錯(cuò)誤時(shí),解釋器就會指出當(dāng)前流已經(jīng)無法繼續(xù)執(zhí)行下去,就出現(xiàn)了異常異常分為兩個(gè)階段:第一個(gè)階段是引起異常發(fā)生的錯(cuò)誤;第二個(gè)階段是檢測并處理階段當(dāng)程序出現(xiàn)錯(cuò)誤,python會自動引發(fā)異常,也可以通過raise顯式地引發(fā)異常一、異常的的基本概念念36一、異常的幾種種表現(xiàn)形式式37一、異常處理的的作用1、提高程序的健壯壯性和容錯(cuò)性2、把晦澀難懂的的錯(cuò)誤提示示轉(zhuǎn)換為友友好提示顯顯示給最終終用戶?可不可以把把所有代碼碼都放到一一個(gè)異常處處理結(jié)構(gòu)中中?影響出錯(cuò)后后的調(diào)試和和代碼維護(hù)護(hù)???可不可以以為每條語語句都配上上異常處理理結(jié)構(gòu)?導(dǎo)致代碼亂亂且龐大??!注意:不建議使用用異常來代代替常規(guī)的的檢查,如如if…else判斷應(yīng)避免過多多使用異常常處理機(jī)制制,只在確確實(shí)需要時(shí)時(shí)采用使用用捕捉異常時(shí)時(shí),應(yīng)盡量量精準(zhǔn),并并針對不同同類型的異異常設(shè)計(jì)不不同的處理理代碼√√√38一、Python中異常類的的層次結(jié)構(gòu)構(gòu)BaseException+--SystemExit+--KeyboardInterrupt+--GeneratorExit+--Exception+--StopIteration+--StandardError|+--BufferError|+--ArithmeticError||+--FloatingPointError||+--OverflowError||+--ZeroDivisionError|+--AssertionError|+--AttributeError|+--EnvironmentError||+--IOError||+--OSError||+--WindowsError||+--VMSError(VMS)點(diǎn)擊此處處編輯文文字闡述述您的論論文內(nèi)容容,點(diǎn)擊擊此處編編輯文字字闡述您您的論文文內(nèi)容,,點(diǎn)擊此此處編輯輯文字闡闡述您的的論文內(nèi)內(nèi)容,點(diǎn)點(diǎn)擊此處處編輯文文字闡述述您的論論文內(nèi)容容,點(diǎn)擊擊此處編編輯文字字闡述您您的論文文內(nèi)容,,點(diǎn)擊此此處編輯輯文字闡闡述您的的論文內(nèi)內(nèi)容。+--Exception+--StandardError|+--EOFError|+--ImportError|+--LookupError||+--IndexError||+--KeyError|+--MemoryError|+--NameError||+--UnboundLocalError|+--ReferenceError|+--RuntimeError||+--NotImplementedError|+--SyntaxError||+--IndentationError||+--TabError|+--SystemError|+--TypeError|+--ValueError39一、Python自定義義異常常類可以繼繼承python內(nèi)置異異常類類來實(shí)實(shí)現(xiàn)自自定義義的異異常類類classDatabaseException(Exception):#繼承python的內(nèi)置置異常常類def__init__(self,err='數(shù)據(jù)庫庫錯(cuò)誤誤'):#在自定定義異異常類類中,,重寫寫父類類init方法Exception.__init__(self,err)classPreconditionsException(DatabaseException):#繼承DatabaseExceptiondef__init__(self,err='PreconditionsErr'):DatabaseException.__init__(self,err)40Python自定義義異常常類如果自自己編編寫某某個(gè)模模塊需需要拋拋出多多個(gè)不不同的的異常常,可可以先先創(chuàng)建建一個(gè)個(gè)基類類,再再創(chuàng)建建多個(gè)個(gè)派生生類分分別表表示不不同的的異常常classMyError(Exception):#基類passclassInputError(MyError):def__int__(self,expression,next,message):#繼承基基類,,新建建派生生類self.expression=expressionself.message=messageclassTransitionError(MyError):def__int__(self,previous,next,message):#繼承基基類,,新建建派生生類self.previous=previousself.next=nextself.message=message4102常見異異常處處理結(jié)結(jié)構(gòu)42二、try…except結(jié)構(gòu)try:try塊#被監(jiān)控控的語語句exceptException[asreason]:except塊#處理異異常的的語句句try:try塊exceptBaseExceptionase:#不建議議這樣樣做except塊……#處理所所有錯(cuò)錯(cuò)誤try子句中中的代代碼塊塊放置置可能能出現(xiàn)現(xiàn)異常常的語語句,,except子句中中的代代碼塊塊處理理異常常當(dāng)需要要捕獲獲所有有異常常時(shí),,可以以使用用BaseException43二、try…except……else結(jié)構(gòu)forarginsys.argv[1:]:try:f=open(arg,'r')exceptIOError:print('cannotopen',arg)else:print(arg,'has',len(f.readlines()),'lines')f.close()如果try范圍內(nèi)內(nèi)捕獲獲了異異常,,就執(zhí)執(zhí)行except塊:如如果try范圍內(nèi)內(nèi)沒有有捕獲獲異常常,就就執(zhí)行行else塊例如::查看看多個(gè)個(gè)文本本,分分析分分別有有多少少行44try:f=open(‘test.txt’’,‘‘r’)line=f.readline()print(line)exceptIOError:print('cannotopenfile')finally:f.close()二、try…except…finally結(jié)構(gòu)try:f=open(‘test.txt’,‘‘r’)line=f.readline()print(line)exceptIOError:print('cannotopenfile')finally:f.close()使用異常處處理結(jié)構(gòu)保保證文件總總是能關(guān)閉閉這樣真的可可以么????使用異常處處理結(jié)構(gòu)的的本意是為為了防止文文件讀取操操作出現(xiàn)異異常而導(dǎo)致致文件不能能正常關(guān)閉閉,但是如如果因?yàn)槲奈募淮嬖谠诙鴮?dǎo)致文文件對象創(chuàng)創(chuàng)建失敗,,那么finally子句中關(guān)閉閉文件對象象的代碼將將會拋出異異常,導(dǎo)致致程序終止止運(yùn)行。45二、帶有多多個(gè)except的try結(jié)構(gòu)try:x=float(input('請輸入被被除數(shù):'))y=float(input('請輸入除除數(shù):'))z=x/yexceptZeroDivisionError:print('除數(shù)數(shù)不能為零零')exceptTypeError:print('被除除數(shù)和除數(shù)數(shù)應(yīng)為數(shù)值值類型')exceptNameError:print('變量量不存在')else:print(x,'/',y,'=',z)46二、帶有多多個(gè)except的try結(jié)構(gòu)importsystry:f=open(‘myfile.txt’’)s=f.readline()i=int(s.trip())f.close()except(OSError,ValueError,RuntimeError,NameError):pass也可以這樣樣寫:將要捕獲的的異常寫在在一個(gè)元組組中,可以以使用一個(gè)個(gè)except語句捕獲多多個(gè)異常::47>>>defdemo_div(a,b):try:returna/bexcept:passfinally:return-1使用帶有finally子句的異常常處理結(jié)構(gòu)構(gòu)時(shí),應(yīng)盡盡量避免在在finally子句中使用用return語句,否則則可能會出出現(xiàn)出乎意意料的錯(cuò)誤誤。二、try…except…finally結(jié)構(gòu)>>>demo_div(1,0)-1>>>demo_div(1,2)-148>>>defdiv(x,y)try:print(x/y)exceptZeroDivisionError:print(‘ZeroDivisionError’’)exceptTypeError:print(‘TypeError’’)else:print(‘NoError’)finally:print(‘executingfinallyclause’)Python異常處理結(jié)結(jié)構(gòu)中可以以同時(shí)包含含多個(gè)except子句、else子句和finally子句二、try…except…except…else…finally結(jié)構(gòu)49斷言assert斷言語句的的語法是:assertexpression[,reason]assertlen(lists)>=5,‘列表元素素個(gè)數(shù)小于于5’assert2==1,'2不等于于1'當(dāng)判斷表達(dá)達(dá)式expression為真時(shí),什什么都不做做;如果表表達(dá)式為假假,則拋出出異常。使用assert斷言是學(xué)習(xí)習(xí)python一個(gè)非常好好的習(xí)慣,在沒完善一個(gè)個(gè)程序之前前,我們不不知道程序序在哪里會會出錯(cuò),與與其讓它在在運(yùn)行時(shí)崩潰潰,不如在出出現(xiàn)錯(cuò)誤條條件時(shí)就崩崩潰,這時(shí)時(shí)候就需要要assert斷言的幫助助。斷言語句assert也是一一種比較常常用的技術(shù)術(shù),常用來來在程序的的某個(gè)位置置確認(rèn)指定定條件必須須滿足,常常和異常處處理結(jié)構(gòu)一一起使用50With上下文管理理語句在Python2.5中with關(guān)鍵字被加入,它是用來替代代try…except…finally…的模式。1、使用with自動關(guān)閉資資源,可以以在代碼塊塊執(zhí)行完畢畢后還原進(jìn)進(jìn)入該代碼碼塊時(shí)的現(xiàn)現(xiàn)場。2、不論何種種原因跳出出with塊,不論是是否發(fā)生異異常,總能能保證文件件被正確關(guān)關(guān)閉,資源源被正確釋釋放。3、用于文件使用后自動動關(guān)閉,線線程中鎖的的自動獲取取和釋放withEXPR[asVAR]:BLOCKEXPR可以是任意表達(dá)式asVAR是可選的((起別名))BLOCK是with語句的語句句體51With上下文管理理語句——案例file=open("/tmp/foo.txt")data=file.read()file.close()try:f=open('xxx')except:print'failtoopen'exit(-1)try:dosomethingexcept:dosomethingelse:f.close()52withopen("/tmp/foo.txt")asfile:data=file.read()02用sys模塊回溯最后的異常常53三、用sys模塊回溯最后的異常54三、用sys模塊回溯最后的異常當(dāng)發(fā)生異常時(shí),Python會回溯異常,給出大量的提示,可能會給程序員的定位和糾錯(cuò)帶來一定的困難,這時(shí)可以使用sys模塊來回溯最近一次異常sys.exc_info()的返回值tuple是一個(gè)三元元組(type,value,traceback)type——————異常的類型型value—————異常的信息息或者參數(shù)數(shù)traceback—————包含調(diào)用棧棧信息的對對象格式如下::>>>importsys>>>try:block>>>except:tuple=sys.exc_info()

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論