python函数的使用场景_Python——异常(内置异常以及应用场景)
"""
什么是異常:
1、異常指出了我們的程序有錯誤
2、有些異常也會在一些合法的情況下發(fā)生,比如用戶名密碼錯誤,銀行卡號不存在
3、內置異常的名字都是以Error結尾:ZeroDivisionError,IndexError,SyntaxError
4、所有異常類都是繼承于Exception,(擴展BaseException)
5、當一個異常發(fā)生的時候,會立即停止程序的執(zhí)行,除非正確的處理這個異常
6、異常是一個對象,并且可以繼承(通過繼承Exception類來實現(xiàn)自己的異常)
"""
#?print?"hello"
#拋出異常信息:SyntaxError:?Missing?parentheses?in?call?to?'print'.?Did?you?mean?print("hello")?
#產生的SyntaxError異常,這就是異常,語法錯誤的異常
#x?=?5?/?0
#print(x)
#拋出ZeroDivisionError異常,信息:ZeroDivisionError:?division?by?zero,說是不能被除
#?lst?=?[1,2,3]
#?print(lst[3])
#拋出異常:IndexError:?list?index?out?of?range?說是索引錯誤
#通過內置的TypeError和ValueError類來構造異常對象,下面的例子擴展了內置的list,并重寫了該內之類的append方法
class?MyList(list):#繼承內置的list類
def?append(self,?integer):
if?not?isinstance(integer,int):#如果不是整數則拋出異常
raise?TypeError("Not?an?integer")
if?integer%?2:
raise?ValueError("Can?not?be?divisible")#不能整除時則拋出異常
super().append(integer)#調用父類的append方法
#?mylist?=?MyList()
#?#mylist.append(12.45)?#引發(fā)TypeError異常
#?#mylist.append(87)?#引發(fā)ValueError異常
#?mylist.append(64)?#無異常
#發(fā)生異常時,程序是怎樣的?
def?test_return():
print("hello")#這條是會被執(zhí)行的
raise?Exception("My?God,?something?went?wrong")#這里引發(fā)異常后,后面的代碼永遠不會執(zhí)行,包括return語句
print("How?are?you?")
return?"I'm?very?good"
#test_return()
#通過另外一個函數來調用test_return函數,看看效果
def?call_test_return():
print("start?call...")
test_return()#在這里調用test_return函數
print("an?exception?was?raised....")
print("so...")
#call_test_return()
"""
在call_test_return函數中調用test_return函數,在test_return函數中有異常的發(fā)生
但是對于call_test_return函數是沒有異常語句的??蔀槭裁催Bcall_test_return函數都停止執(zhí)行了呢?
原因是:
異常拋出會停止在call_test_return函數調用棧內所有代碼的執(zhí)行
"""
#即然有異常,就要處理它,如何處理?
#?try:
#?????test_return()
#?except:?#在這里捕捉到了異常,因此輸出下面的print語句
#?????print("test_return?Function?An?exception?occurs")?#提示有異常發(fā)生
#?print("end...")
"""
捕捉了異常,并且在發(fā)生異常時應該做什么,因此,程序沒有被終止掉
對于在test_return函數,在拋出異常的語句之后的代碼是沒有被執(zhí)行的
1、try語句可以包含任何可能會發(fā)生異常的代碼
2、except語句將捕獲任何類型的異常,而不是捕獲有針對性的異常,它是捕獲所有。
3、那么如何捕獲指定的異常類型?看下面代碼
"""
#捕捉指定的異常類型
def?func_a(number):
try:
return?100?/?number
except?ZeroDivisionError:
print("Can?not?be?0")
#?print(func_a(0))?#拋出ZeroDivisionError類型的異常
#?print(func_a("abcdef"))?#拋出TypeError類型的異常,但目前為止的代碼,沒有寫捕獲TypeError類型的異常,因此這個異常無法被捕捉
#也就是說,TypeError異常,不包含在要處理的異常類型中
#那么如何才能同時捕捉多種類型的異常?改進代碼,如下
def?func_b(number):
try:
return?100?/?number
except?(ZeroDivisionError,?TypeError):
print("Unknown?value...")
#?print(func_b(0))
#?print(func_b("abcdef"))
#非常完美,貌似這兩種異常類型都捕捉到了
#但是,這里有一個弊端,就是,我想捕獲不同類型的異常并且對它們做出不同的操作,目前的代碼是無法實現(xiàn)的,
#那么,為了實現(xiàn)這個想法,繼續(xù)改進代碼,如下
def?func_c(number):
try:
return?100?/?number
except?ZeroDivisionError:
print("Unknown?value...")#捕獲到ZeroDivisionError異常,就執(zhí)行此操作
except?TypeError:
print("Value?Type?Error...")#捕獲到TypeError異常,就執(zhí)行這個操作
#?func_c(0)
#?func_c("abc")
#?print(func_c(89))
#因此,非常完美!
#思考一個問題,如果捕獲任何類型的異常再最前面會是什么情況?看如下代碼
def?func_d(number):
try:
return?100?/?number
except?Exception:#捕獲任何異常類型
print("Exception....")
except?ZeroDivisionError:
print("Unknown?value...")
except?TypeError:
print("Value?Type?Error...")
#?func_d(0)
#?func_d("abc")
#效果是,雖然明確知道會發(fā)生哪種類型的異常并有針對性的捕獲,但是捕獲任何類型異常在最前面,導致有針對性的捕獲根本就沒有捕獲
#為什么會這樣?因為ZeroDivisionError,TypeError這些內置的異常類型都是從Exception類繼承而來的,也就是說,已經捕獲了,就沒必要再去有針對性的捕獲。
#OK,那么如果將他們的順序反過來(也就是except?Exception在最后面),又會是啥情況?看下面的代碼(下面的代碼去掉了捕獲TypeError類型)
def?func_e(number):
try:
return?100?/?number
except?ZeroDivisionError:
print("Unknown?value...")
except?Exception:#捕獲任何異常類型
print("all?Exception....")
#?func_e(0)?#這里引發(fā)的是ZeroDivisionError類型的異常
#?func_e("abc")?#這里原本是引發(fā)TypeError類型的異常,但去掉后因此無法捕捉,所以由except?Exception語句來負責捕獲剩下的所有異常
#通過效果,非常完美,而該在怎樣的應用場景去使用它已經不必多說,很顯然知道怎么去應用它了
"""
有沒有注意到,在上面的例子中,捕獲異常之后所做的操作是打印一句話,
但是實際的操作不只是打印一句話,也可以是做別的操作,比如做運算,或者繼續(xù)循環(huán),或者斷開連接等等操作
有一種情況是,我不想僅僅只是做操作,我還想知道它所引發(fā)的異常的具體信息。那么如何查看?看下面的代碼
"""
def?func_f(number):
try:
return?100?/?number
except?ZeroDivisionError?as?err:
print("[Error]:%s?[args]:%s"?%?(err,?err.args))
#?func_f(0)
#這里是通過as關鍵字來捕獲到異常作為變量來訪問,err.args則是獲取傳給函數的參數
#關鍵字as,在異常中使用,是在python3版本中,而對于python2,則使用的是一個逗號
"""
之前說了,把可能發(fā)生異常的代碼丟進try中,那么如果被丟進try的代碼沒有發(fā)生異常呢?
如果沒有異常,不僅要執(zhí)行try中的代碼,并且同時我還需要執(zhí)行別的操作,
如果有異常的發(fā)生,那么就只捕獲異常,并執(zhí)行對應的動作,無需執(zhí)行別的額外操作。
那么請看下面改進后的代碼
"""
def?func_g(number):
try:
ret=??100?/?number
print(ret)
except?ZeroDivisionError?as?err:
print("[Error]:%s?[args]:%s"?%?(err,?err.args))
else:
print("calculation?done...")
#?func_g(5)?#傳入5到函數中進行計算,沒有異常,沒有異常并且也要執(zhí)行else后面的語句,因此達到了目的
#?func_g(0)?#傳入0,則引發(fā)異常,那么僅僅只是執(zhí)行了except中的捕獲操作,else后面的語句沒有被執(zhí)行
"""
上面的代碼似乎非常完美,我又有一個需求,就是語句無論是否發(fā)生異常都將執(zhí)行我指定的操作
改進如下
"""
def?func_h(number):
try:
ret=??100?/?number
print(ret)
except?ZeroDivisionError?as?err:
print("[Error]:%s?[args]:%s"?%?(err,?err.args))
else:
print("calculation?done...")
finally:
print("code?end...")
#?func_h(0)?#傳入0,引發(fā)異常,并且,也繼續(xù)執(zhí)行了finally后面語句,但是else則沒有執(zhí)行,非常完美,達到我的目的
#?func_h(8)?#傳入的是8,沒有異常則無需捕獲,那么else是在沒有異常的情況下才執(zhí)行,那么他執(zhí)行了。這非常正確,finally后面的語句也執(zhí)行了
#通過看到的效果,finally確實是不管有沒有異常的發(fā)生,都確實是會執(zhí)行
總結
以上是生活随笔為你收集整理的python函数的使用场景_Python——异常(内置异常以及应用场景)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mkfontscale没有这个命令_那些
- 下一篇: java 爬虫框架_不知道Python爬