1. 程式人生 > >Python——異常(內置異常以及應用場景)

Python——異常(內置異常以及應用場景)

如果 ror vision ger 問題 原因 指定 目前 需求

""" 什麽是異常: 1、異常指出了我們的程序有錯誤 2、有些異常也會在一些合法的情況下發生,比如用戶名密碼錯誤,銀行卡號不存在 3、內置異常的名字都是以Error結尾:ZeroDivisionError,IndexError,SyntaxError 4、所有異常類都是繼承於Exception,(擴展BaseException) 5、當一個異常發生的時候,會立即停止程序的執行,除非正確的處理這個異常 6、異常是一個對象,並且可以繼承(通過繼承Exception類來實現自己的異常) """ # 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) #引發TypeError異常 # #mylist.append(87) #引發ValueError異常 # mylist.append(64) #無異常 #發生異常時,程序是怎樣的? def test_return(): print("hello") #這條是會被執行的 raise Exception("My God, something went wrong") #這裏引發異常後,後面的代碼永遠不會執行,包括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函數中有異常的發生 但是對於call_test_return函數是沒有異常語句的。可為什麽連call_test_return函數都停止執行了呢? 原因是: 異常拋出會停止在call_test_return函數調用棧內所有代碼的執行 """ #即然有異常,就要處理它,如何處理? # try: # test_return() # except: #在這裏捕捉到了異常,因此輸出下面的print語句 # print("test_return Function An exception occurs") #提示有異常發生 # print("end...") """ 捕捉了異常,並且在發生異常時應該做什麽,因此,程序沒有被終止掉 對於在test_return函數,在拋出異常的語句之後的代碼是沒有被執行的 1、try語句可以包含任何可能會發生異常的代碼 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")) #非常完美,貌似這兩種異常類型都捕捉到了 #但是,這裏有一個弊端,就是,我想捕獲不同類型的異常並且對它們做出不同的操作,目前的代碼是無法實現的, #那麽,為了實現這個想法,繼續改進代碼,如下 def func_c(number): try: return 100 / number except ZeroDivisionError: print("Unknown value...") #捕獲到ZeroDivisionError異常,就執行此操作 except TypeError: print("Value Type Error...") #捕獲到TypeError異常,就執行這個操作 # 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") #效果是,雖然明確知道會發生哪種類型的異常並有針對性的捕獲,但是捕獲任何類型異常在最前面,導致有針對性的捕獲根本就沒有捕獲 #為什麽會這樣?因為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) #這裏引發的是ZeroDivisionError類型的異常 # func_e("abc") #這裏原本是引發TypeError類型的異常,但去掉後因此無法捕捉,所以由except Exception語句來負責捕獲剩下的所有異常 #通過效果,非常完美,而該在怎樣的應用場景去使用它已經不必多說,很顯然知道怎麽去應用它了 """ 有沒有註意到,在上面的例子中,捕獲異常之後所做的操作是打印一句話, 但是實際的操作不只是打印一句話,也可以是做別的操作,比如做運算,或者繼續循環,或者斷開連接等等操作 有一種情況是,我不想僅僅只是做操作,我還想知道它所引發的異常的具體信息。那麽如何查看?看下面的代碼 """ 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,則使用的是一個逗號 """ 之前說了,把可能發生異常的代碼丟進try中,那麽如果被丟進try的代碼沒有發生異常呢? 如果沒有異常,不僅要執行try中的代碼,並且同時我還需要執行別的操作, 如果有異常的發生,那麽就只捕獲異常,並執行對應的動作,無需執行別的額外操作。 那麽請看下面改進後的代碼 """ 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到函數中進行計算,沒有異常,沒有異常並且也要執行else後面的語句,因此達到了目的 # func_g(0) #傳入0,則引發異常,那麽僅僅只是執行了except中的捕獲操作,else後面的語句沒有被執行 """ 上面的代碼似乎非常完美,我又有一個需求,就是語句無論是否發生異常都將執行我指定的操作 改進如下 """ 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,引發異常,並且,也繼續執行了finally後面語句,但是else則沒有執行,非常完美,達到我的目的 # func_h(8) #傳入的是8,沒有異常則無需捕獲,那麽else是在沒有異常的情況下才執行,那麽他執行了。這非常正確,finally後面的語句也執行了 #通過看到的效果,finally確實是不管有沒有異常的發生,都確實是會執行


Python——異常(內置異常以及應用場景)