一、異常的概念
1、什麼是錯誤
錯誤是指由于邏輯或文法等導入一個程式無法正常執行的問題
錯誤的特點
有些錯誤是無法預知的
2、什麼是異常
異常是程式出錯時辨別的一種狀态
當異常發生時,程式不會再向下執行,而轉去調用此函數的地方待處理此錯誤并恢複為正常狀态
異常的作用
用作信号,通知上層調用者有錯誤需要處理
二、try語句
1、try-except語句文法
文法
try:
可能觸發異常的語句
except 錯誤類型1 [as 變量1]:
異常處理語句1
except 錯誤類型2 [as 變量2]:
異常處理語句2
except (錯誤類型3, 錯誤類型4) [as 變量3]:
異常處理語句3
...
except:
異常處理語句other
else:
末發生異常語句
finally:
最終語句
作用
嘗試捕獲異常,将程式轉為正常狀态并繼續執行
說明
a、as子句是用于綁定錯誤對象的變量,可以省略
b、except 子句可以有一個或多個,但至少要有一個
c、else 子句最多隻能有一個,也可以省略
d、finally子句最多隻能有一個,也可以省略
示例
def div_apple(n):
"""此示例用分蘋果來示意捕捉異常"""
print("%d個蘋果您想分給幾個人?" % n)
s = input("請輸入人數: ")
cnt = int(s) # <--此處可能觸發ValueError類型的錯誤
result = n / cnt # <-- 此處可能會觸發ZeroDivisionError類型的錯誤
print("每個人分了%d個蘋果" % result)
try:
div_apple(10) # 此函數可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except ValueError:
print("分蘋果失敗,程式已捕獲通知并轉為正常狀态")
except ZeroDivisionError:
print("沒有人來,那蘋果就拿來回吧!")
print("程式正常退出")
多個類型錯誤異常,處理的方式一樣
try:
div_apple(10) # 此函數可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except (ValueError, ZeroDivisionError): # 多個類型錯誤異常, 處理的方式一樣
print("蘋果不分了")
print("程式正常退出")
當錯誤類型不比對時,調用except : 在這裡處理
try:
div_apple(10) # 此函數可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except ValueError:
print("蘋果不分了")
except:
print("其它類型的錯誤已捕獲!")
print("程式正常退出")
完整(as、else、finally)
try:
div_apple(10) # 此函數可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except ValueError:
print("蘋果不分了")
except exception as e:
print("其它類型的錯誤已捕獲!", e)
else:
# 此處語句隻有在沒有發生異常時才會執行
print("分蘋果時沒有發生異常")
finally:
# finally 子句中的内容在任何情況下都會被執行
print("我一定會執行的!!!!!")
print("程式正常退出")
2、try-finally 語句
文法
try:
可能觸發異常的語句
finally:
一定要執行的最終語句
說明
a、finally 子句不可以省略
b、一定不存在except子句
作用
通常用try-finally語句來做觸發異常時必須要處理的事情,無論異常是否發生,finally子句都會被執行
注:try-finally 語句不會改變程式的狀态(正常/異常)狀态
示例
def fry_egg():
print('打開天瓦斯....')
try:
count = int(input("請輸入雞蛋個數: "))
print("共煎了", count, '個雞蛋')
finally:
print('關閉天瓦斯')
try:
fry_egg()
except ValueError:
pass
print("程式正常執行")
三、raise 語句
作用
觸發一個錯誤,讓程式進入異常狀态
文法
raise 異常類型
或
raise 異常對象
示例
def make_exception(n):
# 假設n必須是0-100的整數
print("begin....")
# 觸發ValueError類型的異常并進入異常狀态
# raise 異常類型
if n > 100:
raise ValueError
# raise 異常對象
if n < 0:
raise ValueError("這是我自己定義的一個錯誤")
print("end")
value = int(input("請輸入一個整數:"))
try:
make_exception(value)
print("make_exception調用結束")
except ValueError as e:
print("try裡出現了值錯誤通知,已捕獲!!!")
print("接收的異常通知是: ", e)
四、assert 語句(斷言語句)
文法
assert 真值表達式,錯誤資料(通常是字元串)
作用
當真值表達式為False時,用錯誤資料建立一個 AssertionError 類型的錯誤,并進入異常狀态
等同于:
if 真值表達式 == False:
raise AssertionError(錯誤資料)
示例
def get_score():
s = int(input("請輸入學生成績: "))
# 用assert語句來斷言s是否在 0~100之間
assert 0 <= s <= 100, "使用者輸入的整數不在0~100之間"
return s
try:
score = get_score()
print("學生成績為:", score)
except ValueError:
print("使用者輸入的成績無法轉化為整數")
except AssertionError as err:
print("發生了斷言錯誤,原因是:", err)
五、with語句(進階)
文法
with 表達式1 [as 變量1],表達式2 [as 變量2], ...:
語句塊
作用
使用于對資源進行通路的場合,確定使用過程中不管是否發生異常,都會執行必須的'清理'操作,并釋放資源
如: 檔案使用後自動關閉,線程中鎖的自動擷取和釋放等
說明
a、執行表達式 用as 子句中的變量綁定生成的對象
b、with 語句并不會改變異常的狀态,通常在最外層加try-except語句
示例
src_file = input("請輸入源檔案: ")
dst_file = input("請輸入目标檔案: ")
try:
with open(src_file, 'rb') as src:
# 準備打開别一個檔案
with open(dst_file, 'wb') as dst:
# 開始讀寫檔案
b = src.read()
dst.write(b)
except OSError:
print("複制失敗")
六、綜合
1、為什麼要用異常處理機制
在程式調用層數較深時,向主調函數傳遞錯誤資訊需要層層return傳回比較麻煩,是以用異常處理機制來解決此類問題
2、異常小結
語句
try-except
捕獲異常,償試接收異常通知
try-finally
執行一定要執行的語句
raise
發送異常通知,将程式轉為異常狀态(進入異常流程)
assert
根據條件來觸發AssertionError類型的異常
with IO操作
七、附錄
人工智能(python)—— 目錄彙總