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

下載本文檔

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

文檔簡(jiǎn)介

1、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ù)定義語(yǔ)法: def 函數(shù)名(參數(shù)列表): 注釋

2、 函數(shù)體函數(shù)形參不需要聲明類型,也不需要指定函數(shù)返回值類型即使該函數(shù)不需要接收任何參數(shù),也必須保留一對(duì)空的圓括號(hào)括號(hào)后面的冒號(hào)必不可少函數(shù)體相對(duì)于def關(guān)鍵字必須保持一定的空格縮進(jìn)Python允許嵌套定義函數(shù)注意事項(xiàng)3函數(shù)定義格式生成斐波那契數(shù)列的函數(shù)定義和調(diào)用:調(diào)用函數(shù)1000是實(shí)參n是形參def fib(n): a, b = 1, 1 while a def func(): print(func.x) #查看func的成員 func() #現(xiàn)在函數(shù)func還沒有成員x,出錯(cuò)AttributeError: function object has no attribute xfunc.x =

3、3 #動(dòng)態(tài)為函數(shù)增加新成員func()3del func.x #刪除成員func() #刪除之后不可訪問AttributeError: function object has no attribute x6函數(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)用的位置需要用棧來存儲(chǔ)該函數(shù)離開的位置,棧比較小,如果遞歸調(diào)用很深,則導(dǎo)致棧崩潰7尾遞歸尾遞歸是指:在函數(shù)返回的時(shí)候,調(diào)用自身本身,并且,return語(yǔ)句不能包含表達(dá)式。這樣,編譯器或者解釋器就可以把尾遞歸做優(yōu)化,使遞歸

4、本身無論調(diào)用多少次,都只占用一個(gè)棧幀,不會(huì)出現(xiàn)棧溢出的情況。8遞歸實(shí)現(xiàn)n的階乘:def fact(n): if n=1: return 1 return n * fact(n - 1)def fact(n): return fact_iter(n, 1)def fact_iter(num, product): if num = 1: return product return fact_iter(num - 1, num * product)改成尾遞歸return fact_iter(num - 1, num * product) 僅返回遞歸函數(shù)本身num - 1和num * product在

5、函數(shù)調(diào)用前就會(huì)被計(jì)算,不影響函數(shù)調(diào)用遺憾的是:大多數(shù)編程語(yǔ)言沒有針對(duì)尾遞歸做優(yōu)化,Python解釋器也沒有做優(yōu)化,所以,即使把上面的fact(n)函數(shù)改成尾遞歸方式,也會(huì)導(dǎo)致棧溢出010203在Python中,定義函數(shù)時(shí)不需要聲明函數(shù)的返回值類型,而是使用return語(yǔ)句結(jié)束函數(shù)的執(zhí)行的同時(shí)返回任意類型的值,函數(shù)返回值類型與return語(yǔ)句返回表達(dá)式的類型一致。如果函數(shù)沒有return語(yǔ)句或者執(zhí)行了不返回任何值的return語(yǔ)句,Python將認(rèn)為該函數(shù)以return None結(jié)束,即返回空值函數(shù)基本語(yǔ)法9不論return語(yǔ)句出現(xiàn)在函數(shù)的什么位置,一旦得到執(zhí)行將直接結(jié)束函數(shù)的執(zhí)行。函數(shù)參數(shù)不得

6、不說的幾件事(一)1)在定義函數(shù)時(shí),對(duì)參數(shù)個(gè)數(shù)并沒有限制,如果有多個(gè)形參,則需要使用逗號(hào)進(jìn)行分隔.下面的函數(shù)用來接收2個(gè)參數(shù),并輸出其中的最大值:def printMax(a, b): if ab: pirnt(a, is the max) else: print(b, is the max)2)對(duì)于絕大多數(shù)情況下,在函數(shù)內(nèi)部直接修改形參的值不會(huì)影響實(shí)參 : def addOne(a): print(a) #輸出原變量a的值 a += 1 #這條語(yǔ)句會(huì)得到一個(gè)新的變量a print(a) a = 3 addOne(a)34 a310函數(shù)參數(shù)不得不說的幾件事(二)在有些情況下,可以通過特殊的方式

7、在函數(shù)內(nèi)部修改實(shí)參的值。 def modify(v): #修改列表元素值 v0 = v0+1 a = 2 modify(a) a3 def modify(v, item): #為列表增加元素 v.append(item) a = 2 modify(a, 3) a2, 3 def modify(d): #修改字典元素值或?yàn)樽值湓黾釉?dage = 38 a = name:Dong, age:37, sex:Male aage: 37, name: Dong, sex: Male modify(a) aage: 38, name: Dong, sex: Male11函數(shù)參數(shù)不得不說的幾件事(三)

8、默認(rèn)值參數(shù)在調(diào)用帶有默認(rèn)值參數(shù)的函數(shù)時(shí),可以不用為設(shè)置了默認(rèn)值的形參進(jìn)行傳值,此時(shí)函數(shù)將會(huì)直接使用函數(shù)定義時(shí)設(shè)置的默認(rèn)值,也可以通過顯式賦值來替換其默認(rèn)值。def 函數(shù)名(,形參名=默認(rèn)值): 函數(shù)體可以使用“函數(shù)名._defaults_”隨時(shí)查看函數(shù)所有默認(rèn)值參數(shù)的當(dāng)前值,其返回值為一個(gè)元組,其中的元素依次表示每個(gè)默認(rèn)值參數(shù)的當(dāng)前值。 def say( 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ù)

9、名字傳遞值,實(shí)參順序可以和形參順序不一致,但不影響參數(shù)值的傳遞結(jié)果,避免了用戶需要牢記參數(shù)位置和順序的麻煩,使得函數(shù)的調(diào)用和參數(shù)傳遞更加靈活方便。 def demo(a, b, c=5): print(a, b, c) demo(c=8, a=9, b=0)9 0 813函數(shù)參數(shù)不得不說的幾件事(五)(3)可變長(zhǎng)度參數(shù)可變長(zhǎng)度參數(shù)在定義函數(shù)時(shí)主要有兩種形式:*parameter和*parameter,前者用來接收任意多個(gè)實(shí)參并將其放在一個(gè)元組中,后者接收類似于關(guān)鍵參數(shù)一樣顯式賦值形式的多個(gè)實(shí)參并將其放入字典中。第一種形式可變長(zhǎng)度參數(shù)的用法,無論調(diào)用該函數(shù)時(shí)傳遞了多少實(shí)參,一律將其放入元組中:

10、def demo(*p): print(p) demo(1, 2, 3, 4, 5, 6, 7)(1, 2, 3, 4, 5, 6, 7)第二種形式可變長(zhǎng)度參數(shù)的用法: def demo(*p): for item in p.items(): print(item) demo(x=1, y=2, z=3)(y, 2)(x, 1)(z, 3)14函數(shù)參數(shù)不得不說的幾件事(六)傳遞參數(shù)時(shí)的序列解包 def demo(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,

11、 3:c demo(*dic)6 Set = 1, 2, 3 demo(*Set)6 demo(*dic.values()abc15Key作為實(shí)參函數(shù)參數(shù)不得不說的幾件事(七)注意:調(diào)用函數(shù)時(shí)如果對(duì)實(shí)參使用一個(gè)星號(hào)*進(jìn)行序列解包,這么這些解包后的實(shí)參將會(huì)被當(dāng)做普通位置參數(shù)對(duì)待,并且會(huì)在關(guān)鍵參數(shù)和使用兩個(gè)星號(hào)*進(jìn)行序列解包的參數(shù)之前進(jìn)行處理。 def demo(a, b, c): #定義函數(shù) print(a, b, c) demo(a=1, *(2, 3) #序列解包相當(dāng)于位置參數(shù),優(yōu)先處理Traceback (most recent call last): File , line 1, in

12、demo(a=1, *(2, 3)TypeError: demo() got multiple values for argument a demo(c=1, *(2, 3)2 3 1 demo(*a:1, b:2, *(3,) #序列解包不能在關(guān)鍵參數(shù)解包之后SyntaxError: iterable argument unpacking follows keyword argument unpacking demo(*(3,), *c:1, b:2)3 2 116參數(shù)檢查調(diào)用函數(shù)時(shí),如果參數(shù)個(gè)數(shù)不對(duì),Python解釋器會(huì)自動(dòng)檢查出來,并拋出TypeError:17def my_abs(x)

13、: if x = 0: return x else: return -x my_abs(1, 2)Traceback (most recent call last): File , line 1, in TypeError: my_abs() takes 1 positional argument but 2 were given如果參數(shù)類型不對(duì),Python解釋器就無法幫我們檢查。看一下 my_abs和內(nèi)置函數(shù)abs的差別: my_abs(A)Traceback (most recent call last): File , line 1, in File , line 2, in my_a

14、bsTypeError: unorderable types: str() = int() abs(A)Traceback (most recent call last): File , line 1, in TypeError: bad operand type for abs(): str參數(shù)檢查我們修改一下my_abs的定義,對(duì)參數(shù)類型做檢查,只允許整數(shù)和浮點(diǎn)數(shù)類型的參數(shù)。數(shù)據(jù)類型檢查可以用內(nèi)置函數(shù)isinstance()實(shí)現(xiàn):18def my_abs(x): if not isinstance(x, (int, float): raise TypeError(bad operand t

15、ype) if x = 0: return x else: return -x my_abs(A)Traceback (most recent call last): File , line 1, in File , line 3, in my_absTypeError: bad operand type變量的作用域1、變量起作用的代碼范圍稱為變量的作用域,不同作用域內(nèi)變量名可以相同,互不影響2、在函數(shù)內(nèi)部定義的普通變量只在函數(shù)內(nèi)部起作用,稱為局部變量。當(dāng)函數(shù)執(zhí)行結(jié)束后,局部變量自動(dòng)刪除,不再可以使用3、局部變量的引用比全局變量速度快,應(yīng)優(yōu)先考慮使用1、一個(gè)變量已在函數(shù)外定義,如果在函數(shù)內(nèi)需要

16、為這個(gè)變量賦值,并要將這個(gè)賦值結(jié)果反映到函數(shù)外,可以在函數(shù)內(nèi)使用global將其聲明為全局變量。2、如果一個(gè)變量在函數(shù)外沒有定義,在函數(shù)內(nèi)部也可以直接將一個(gè)變量定義為全局變量,該函數(shù)執(zhí)行后,將增加一個(gè)新的全局變量。n全局變量可以通過關(guān)鍵字global來定義。這分為兩種情況:19 def demo(): global x x = 3 y = 4 print(x,y) x = 5 demo()3 4 x3 yNameError: name y is not defined del x xNameError: name x is not defined demo()3 4 x3 yNameError

17、: name y is not defined變量的作用域例子20如果局部變量與全局變量具有相同的名字,那么該局部變量會(huì)在自己的作用域內(nèi)隱藏同名的全局變量。 def demo(): x = 3 #創(chuàng)建了局部變量,并自動(dòng)隱藏了同名的全局變量print(x) x = 5 demo()3 x #函數(shù)執(zhí)行不影響外面全局變量的值5變量的作用域例子21n 如果需要在同一個(gè)程序的不同模塊之間共享全局變量的話,可以編寫一個(gè)專門的模塊來實(shí)現(xiàn)這一目的。例如,假設(shè)在模塊A.py中有如下變量定義: global_variable = 0n 而在模塊B.py中包含以下用來設(shè)置全局變量的語(yǔ)句:import AA.glob

18、al_variable = 1n 在模塊C.py中有以下語(yǔ)句來訪問全局變量的值:import Aprint(A.global_variable)變量的作用域例子22lambda表達(dá)式可以用來聲明匿名函數(shù),也就是沒有函數(shù)名字的臨時(shí)使用的小函數(shù),尤其適合需要一個(gè)函數(shù)作為另一個(gè)函數(shù)參數(shù)的場(chǎng)合。也可以定義匿名函數(shù)。lambda表達(dá)式只可以包含一個(gè)表達(dá)式,該表達(dá)式的計(jì)算結(jié)果可以看作是函數(shù)的返回值,不允許包含復(fù)合語(yǔ)句,但在表達(dá)式中可以調(diào)用其他函數(shù)。Lambda 表達(dá)式格式: f = lambda x, y, z: x+y+z #可以給lambda表達(dá)式起名字 f(1,2,3) #像函數(shù)一樣調(diào)用6 g =

19、lambda x, y=2, z=3: x+y+z #參數(shù)默認(rèn)值 g(1)6 g(2, z=4, y=5) #關(guān)鍵參數(shù)1123 L = (lambda x: x*2), (lambda x: x*3), (lambda x: x*4) print(L0(2),L1(2),L2(2)4 8 16 D = f1:(lambda:2+3), f2:(lambda:2*3), f3:(lambda:2*3) print(Df1(), Df2(), Df3()5 6 8 L = 1,2,3,4,5 print(list(map(lambda x: x+10, L) #模擬向量運(yùn)算11, 12, 13,

20、14, 15 L1, 2, 3, 4, 5Lambda 表達(dá)式24 data = list(range(20) #創(chuàng)建列表 data0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 import random random.shuffle(data) #打亂順序 data4, 3, 11, 13, 12, 15, 9, 2, 10, 6, 19, 18, 14, 8, 0, 7, 5, 17, 1, 16 data.sort(key=lambda x: x) #和不指定規(guī)則效果一樣 data0, 1, 2,

21、 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 data.sort(key=lambda x: len(str(x) #按轉(zhuǎn)換成字符串以后的長(zhǎng)度排序 data0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 data.sort(key=lambda x: len(str(x), reverse=True) #降序排序 data10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4,

22、5, 6, 7, 8, 9Lambda 表達(dá)式25函數(shù)可以返回多個(gè)值嗎?答案是肯定的。比如在游戲中經(jīng)常需要從一個(gè)點(diǎn)移動(dòng)到另一個(gè)點(diǎn),給出坐標(biāo)、位移和角度,就可以計(jì)算出新的坐標(biāo):import mathdef move(x, y, step, angle=0): nx = x + step * math.cos(angle) ny = y - step * math.sin(angle) return nx, ny函數(shù)返回多個(gè)值(一)26import mathdef move(x, y, step, angle=0): nx = x + step * math.cos(angle) ny = y -

23、 step * math.sin(angle) return nx, ny27x, y = move(100, 100, 60 ,math.pi/6)print(x,y)151.96152422706632 70.0但其實(shí)這只是一種假象,Python函數(shù)返回的仍然是單一值。 r = move(100, 100, 60, math.pi / 6) print(r)(151.96152422706632, 70.0)原來返回值是一個(gè)tuple!多個(gè)變量可以同時(shí)接收一個(gè)tuple,按位置賦給對(duì)應(yīng)的值,所以,Python的函數(shù)返回多值其實(shí)就是返回一個(gè)tuple函數(shù)返回多個(gè)值(二)例1 編寫函數(shù),接收包

24、含20個(gè)整數(shù)的列表lst和一個(gè)整數(shù)k作為參數(shù),返回新列表。處理規(guī)則為:將列表lst中下標(biāo)k之前的元素逆序,下標(biāo)k之后的元素逆序,然后將整個(gè)列表lst中的所有元素逆序。def demo(lst, k): x = lst:k x.reverse() y = lstk: y.reverse() r = x+y return list(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, 20print(demo(lst, 5)6, 7

25、, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 2, 3, 4, 5案例精選(一)28例2 編寫函數(shù),接收一個(gè)正偶數(shù)為參數(shù),輸出兩個(gè)素?cái)?shù),并且這兩個(gè)素?cái)?shù)之和等于原來的正偶數(shù)。如果存在多組符合條件的素?cái)?shù),則全部輸出。import mathdef IsPrime(n): m = int(math.sqrt(n)+1 for i in range(2, m): if n%i=0: return False return Truedef demo(n): if isinstance(n, int) and n0 and n%2=0: for

26、 i in range(3, int(n/2)+1): if i%2=1 and IsPrime(i) and IsPrime(n-i): print(i, +, n-i, =, n)demo(60)7 + 53 = 60 13 + 47 = 60 17 + 43 = 60 19 + 41 = 60 23 + 37 = 60 29 + 31 = 60案例精選(二)29例3 編寫函數(shù),接收兩個(gè)正整數(shù)作為參數(shù),返回一個(gè)元組,其中第一個(gè)元素為最大公約數(shù),第二個(gè)元素為最小公倍數(shù)。def demo(m, n): if mn: m, n = n, m p = m*n while m!=0: r = n%m

27、 n = m m = r return (n, int(p/n)print(demo(20, 30)(10,60)案例精選(三)30函數(shù)設(shè)計(jì)與使用小結(jié)1、定義函數(shù)時(shí),需要確定函數(shù)名和參數(shù)個(gè)數(shù)2、如果有必要,可以先對(duì)參數(shù)的數(shù)據(jù)類型做檢查3、函數(shù)體內(nèi)部可以用return隨時(shí)返回函數(shù)結(jié)果4、函數(shù)執(zhí)行完畢也沒有return語(yǔ)句時(shí),自動(dòng)return None5、函數(shù)可以同時(shí)返回多個(gè)值,但其實(shí)就是一個(gè)tuple31Python 異常處理結(jié)構(gòu)32“ ”小故事 歐洲阿麗亞娜5型火箭經(jīng)過近十年研發(fā),1996年首次發(fā)射失敗,火箭和箭上衛(wèi)星全毀,造成巨大經(jīng)濟(jì)損失。事故起因是新火箭直接繼承了4型火箭“久經(jīng)考驗(yàn)”的控制

28、系統(tǒng),但5型火箭加速度大造成傳感器讀數(shù)大,導(dǎo)致一次從浮點(diǎn)數(shù)到整數(shù)的數(shù)值轉(zhuǎn)換溢出。慣性導(dǎo)航系統(tǒng)失效后飛行狀態(tài)失控,控制系統(tǒng)關(guān)閉了火箭的狀態(tài)調(diào)節(jié)系統(tǒng),安全系統(tǒng)最后引爆火箭自毀。33箭載軟件出錯(cuò)的原因是,沒有達(dá)到軟件容錯(cuò)的目標(biāo)異常的基礎(chǔ)知識(shí)34“ ”異常概述簡(jiǎn)單地說,異常是指程序運(yùn)行時(shí)引發(fā)的錯(cuò)誤,引發(fā)錯(cuò)誤的原因有很多,例如除零、下標(biāo)越界、文件不存在、網(wǎng)絡(luò)異常、類型錯(cuò)誤、名字錯(cuò)誤、字典鍵錯(cuò)誤、磁盤空間不足,等等。如果這些錯(cuò)誤得不到正確的處理,將會(huì)導(dǎo)致程序終止運(yùn)行,而合理地使用異常處理結(jié)果,可以使得程序更加健壯, 具有更強(qiáng)的容錯(cuò)性,不會(huì)因?yàn)橛脩舨恍⌒牡腻e(cuò)誤輸入或其他運(yùn)行時(shí)原因而造成程序中止。350102

29、0304語(yǔ)法錯(cuò)誤和邏輯錯(cuò)誤不屬于異常,但有些語(yǔ)法錯(cuò)誤往往會(huì)導(dǎo)致異常,例如由于大小寫拼寫錯(cuò)誤而訪問不存在的對(duì)象異常是指因?yàn)槌绦虺鲥e(cuò)而在正常控制流以外采取的行為,當(dāng)python檢測(cè)到一個(gè)錯(cuò)誤時(shí),解釋器就會(huì)指出當(dāng)前流已經(jīng)無法繼續(xù)執(zhí)行下去,就出現(xiàn)了異常異常分為兩個(gè)階段:第一個(gè)階段是引起異常發(fā)生的錯(cuò)誤;第二個(gè)階段是檢測(cè)并處理階段當(dāng)程序出現(xiàn)錯(cuò)誤,python會(huì)自動(dòng)引發(fā)異常,也可以通過raise顯式地引發(fā)異常一、異常的基本概念36一、異常的幾種表現(xiàn)形式37一、異常處理的作用1、提高程序的健壯性和容錯(cuò)性2、把晦澀難懂的錯(cuò)誤提示轉(zhuǎn)換為友好提示顯示給最終用戶?可不可以把所有代碼都放到一個(gè)異常處理結(jié)構(gòu)中?影響出錯(cuò)后

30、的調(diào)試和代碼維護(hù)!?可不可以為每條語(yǔ)句都配上異常處理結(jié)構(gòu)?導(dǎo)致代碼亂且龐大!注意:不建議使用異常來代替常規(guī)的檢查,如ifelse 判斷應(yīng)避免過多使用異常處理機(jī)制,只在確實(shí)需要時(shí)采用使用捕捉異常時(shí),應(yīng)盡量精準(zhǔn),并針對(duì)不同類型的異常設(shè)計(jì)不同的處理代碼38一、 Python中異常類的層次結(jié)構(gòu)BaseException +- SystemExit +- KeyboardInterrupt +- GeneratorExit +- Exception +- StopIteration +- StandardError | +- BufferError | +- ArithmeticError | | +-

31、 FloatingPointError | | +- OverflowError | | +- ZeroDivisionError | +- AssertionError | +- AttributeError | +- EnvironmentError | | +- IOError | | +- OSError | | +- WindowsError | | +- VMSError (VMS)點(diǎn)擊此處編輯文字闡述您的論文內(nèi)容,點(diǎn)擊此處編輯文字闡述您的論文內(nèi)容,點(diǎn)擊此處編輯文字闡述您的論文內(nèi)容,點(diǎn)擊此處編輯文字闡述您的論文內(nèi)容,點(diǎn)擊此處編輯文字闡述您的論文內(nèi)容,點(diǎn)擊此處編輯文字闡述您的論文內(nèi)容

32、。+- Exception +- StandardError | +- EOFError | +- ImportError | +- LookupError | | +- IndexError | | +- KeyError | +- MemoryError | +- NameError | | +- UnboundLocalError | +- ReferenceError | +- RuntimeError | | +- NotImplementedError | +- SyntaxError | | +- IndentationError | | +- TabError | +- Sys

33、temError | +- TypeError | +- ValueError 39一、 Python 自定義異常類可以繼承python內(nèi)置異常類來實(shí)現(xiàn)自定義的異常類class DatabaseException(Exception): #繼承python的內(nèi)置異常類 def _init_(self,err=數(shù)據(jù)庫(kù)錯(cuò)誤): #在自定義異常類中,重寫父類init方法 Exception._init_(self,err) class PreconditionsException(DatabaseException): #繼承DatabaseException def _init_(self,err

34、=PreconditionsErr): DatabaseException._init_(self,err)40Python 自定義異常類如果自己編寫某個(gè)模塊需要拋出多個(gè)不同的異常,可以先創(chuàng)建一個(gè)基類,再創(chuàng)建多個(gè)派生類分別表示不同的異常class MyError(Exception): #基類 passclass InputError(MyError): def _int_(self, expression, next, message): #繼承基類,新建派生類 self.expression = expression self.message = messageclass Transiti

35、onError(MyError): def _int_(self, previous, next, message): #繼承基類,新建派生類 self.previous = previous self.next = next self.message = message41常見異常處理結(jié)構(gòu)42二、tryexcept結(jié)構(gòu)try: try塊 #被監(jiān)控的語(yǔ)句except Exception as reason: except 塊 #處理異常的語(yǔ)句try: try塊 except BaseException as e: #不建議這樣做 except 塊 #處理所有錯(cuò)誤try子句中的代碼塊放置可能出現(xiàn)

36、異常的語(yǔ)句,except子句中的代碼塊處理異常當(dāng)需要捕獲所有異常時(shí),可以使用BaseException43二、tryexceptelse結(jié)構(gòu)for arg in sys.argv1: try: f = open(arg, r) except IOError: print(cannot open, arg) else: print(arg, has, len(f.readlines(), lines) f.close()如果try范圍內(nèi)捕獲了異常,就執(zhí)行except塊:如果try范圍內(nèi)沒有捕獲異常,就執(zhí)行else塊例如:查看多個(gè)文本,分析分別有多少行44try: f = open(test.tx

37、t, r) line = f.readline() print(line)except IOError: print(cannot open file)finally: f.close()二、tryexceptfinally結(jié)構(gòu)try: f = open(test.txt, r) line = f.readline() print(line)except IOError: print(cannot open file)finally: f.close()使用異常處理結(jié)構(gòu)保證文件總是能關(guān)閉這樣真的可以么?使用異常處理結(jié)構(gòu)的本意是為了防止文件讀取操作出現(xiàn)異常而導(dǎo)致文件不能正常關(guān)閉,但是如果因?yàn)槲募?/p>

38、不存在而導(dǎo)致文件對(duì)象創(chuàng)建失敗,那么finally子句中關(guān)閉文件對(duì)象的代碼將會(huì)拋出異常,導(dǎo)致程序終止運(yùn)行。45二、帶有多個(gè)except的try結(jié)構(gòu)try: x = float(input(請(qǐng)輸入被除數(shù): ) y = float(input(請(qǐng)輸入除數(shù): ) z = x / yexcept ZeroDivisionError: print(除數(shù)不能為零)except TypeError: print(被除數(shù)和除數(shù)應(yīng)為數(shù)值類型)except NameError: print(變量不存在)else: print(x, /, y, =, z)46二、帶有多個(gè)except的try結(jié)構(gòu)import syst

39、ry: f = open(myfile.txt) s = f.readline() i = int(s.trip() f.close()except (OSError, ValueError, RuntimeError, NameError): pass也可以這樣寫:將要捕獲的異常寫在一個(gè)元組中,可以使用一個(gè)except語(yǔ)句捕獲多個(gè)異常:47def demo_div(a, b): try: return a/b except: pass finally: return -1使用帶有finally子句的異常處理結(jié)構(gòu)時(shí),應(yīng)盡量避免在finally子句中使用return語(yǔ)句,否則可能會(huì)出現(xiàn)出乎意料的

40、錯(cuò)誤。二、tryexceptfinally結(jié)構(gòu)demo_div(1, 0)-1demo_div(1, 2)-148def div(x,y) try : print(x/y) except ZeroDivisionError: print(ZeroDivisionError) except TypeError: print(TypeError) else: print(No Error) finally: print(executing finally clause)Python異常處理結(jié)構(gòu)中可以同時(shí)包含多個(gè)except子句、else子句和finally子句二、tryexceptexceptel

41、sefinally結(jié)構(gòu)49斷言assert 斷言語(yǔ)句的語(yǔ)法是:assert expression , reasonassert len(lists) =assert len(lists) =5 5,列表元素個(gè)數(shù)小于5 5assert assert 2=12=1,2 2不等于1 1 當(dāng)判斷表達(dá)式expression為真時(shí),什么都不做;如果表達(dá)式為假,則拋出異常。使用assert斷言是學(xué)習(xí)python一個(gè)非常好的習(xí)慣, 在沒完善一個(gè)程序之前,我們不知道程序在哪里會(huì)出錯(cuò),與其讓它在運(yùn)行時(shí)崩潰,不如在出現(xiàn)錯(cuò)誤條件時(shí)就崩潰,這時(shí)候就需要assert斷言的幫助。斷言語(yǔ)句assert也是一種比較常用的技術(shù),

42、常用來在程序的某個(gè)位置確認(rèn)指定條件必須滿足,常和異常處理結(jié)構(gòu)一起使用50With上下文管理語(yǔ)句在Python2.5中with關(guān)鍵字被加入,它是用來替代tryexceptfinally的模式。1、使用with自動(dòng)關(guān)閉資源,可以在代碼塊執(zhí)行完畢后還原進(jìn)入該代碼塊時(shí)的現(xiàn)場(chǎng)。2、不論何種原因跳出with塊,不論是否發(fā)生異常,總能保證文件被正確關(guān)閉,資源被正確釋放。3、用于文件使用后自動(dòng)關(guān)閉,線程中鎖的自動(dòng)獲取和釋放with EXPR as VAR : BLOCKEXPR 可以是任意表達(dá)式 as VAR 是可選的(起別名)BLOCK 是with語(yǔ)句的語(yǔ)句體 51With上下文管理語(yǔ)句案例file = o

43、pen(/tmp/foo.txt) data = file.read() file.close()try: f = open(xxx) except: print fail to open exit(-1) try: do something except: do something else: f.close()52with open(/tmp/foo.txt) as file: data = file.read()用sys模塊回溯最后的異常53三、用sys模塊回溯最后的異常54三、用sys模塊回溯最后的異常當(dāng)發(fā)生異常時(shí),Python會(huì)回溯異常,給出大量的提示,可能會(huì)給程序員的定位和糾錯(cuò)帶來一定的困難,這時(shí)可以使用sys模塊來回溯最近一次異常sys.exc_info()的返回值tuple是一個(gè)三元組(type, value, traceback)type 異常的類型value異常的信息或者參數(shù)traceback包含調(diào)用棧信息的對(duì)象格式如下:import systry: blockexcept: tuple = sys.exc_info() print(tuple)55三、用sys模塊回溯最后的異常def A():1/0

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論