Python——異常(內置異常以及應用場景)
阿新 • • 發佈:2018-01-09
如果 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——異常(內置異常以及應用場景)