1. 程式人生 > >Python中的異常處理

Python中的異常處理

1、異常

1.1 概念引入

什麼是錯誤:  # 會引起程式的異常
錯誤是由於邏輯或者語法等導致一個程式無法正常執行的問題
-------------------------------------------------------------------------
什麼是異常:  # 錯誤發生時的一種狀態
異常是指程式出錯時標識的一種狀態
當異常發生時,程式不會在向下執行,而轉去呼叫此函式的地方待處理錯誤並恢復正常狀態

1.2 作用

用作訊號,通知上層呼叫者有錯誤產生需要處理
在程式呼叫層數較空時,想主調函式傳遞錯誤資訊需要層層return返回比較麻煩,用異常處理機制就相對簡單很多,程式碼量大大減少。

2、處理異常語句 try-except 語句

2.1 try語句的兩種用法

try-except 語句
try-finally語句

2.2 try-except 語法

try:
	可能觸發的異常
except 錯誤型別1 [as 變數1]:
	異常處理語句1
except 錯誤型別2 [as 變數2]:
	異常處理語句2
except (錯誤型別3,錯誤型別4):
	異常處理語句3
	....
except:
	其他異常處理語句
else:
	未發生錯誤執行的語句  ,  發生錯誤不執行
finally:
	最終語句   ,  無論正常還是異常都一定會執行 

2.3 作用

嘗試捕獲異常(接受異常通知),將程式轉為正常狀態並繼續執行

2.4 說明

as 子句用於繫結錯誤物件的變數,可以省略		eg :except ValueError as err
except 子句可以有一個或多個,但至少有一個
else 子句最多隻能有一個,但也可以省略不		# 只有在try語句內部沒錯誤的時候執行,有錯誤不執行
finally 子句最多隻能有一個,但也可以省略不寫	# finally語句無論怎麼樣都一定會執行

2.5 示例1

def div_apple(n):
    print("%d個蘋果你想分給幾個人?"%n)
    s = input('請輸入人數:')
    cnt = int(s)    # 可能觸發 ValueError 錯誤進入異常
    result= n/cnt   # 可能觸發 ZeroDivisionError錯誤進入異常
    print("每個人分了",result,"個蘋果")
try:
    div_apple(10)
    print("蘋果分配完成!")
except ValueError:
    print("在try語句內部發生了值錯誤,已處理並轉為正常狀態!")
except ZeroDivisionError:
    print("不能分配給0個人!")
print("程式正常退出")

示例2:

# 捕獲異常,數輸入1~100的數並輸出,捕獲:超出範圍或者型別錯誤,返回 0
# 也可以在函式外捕獲異常 
def get_score():
    try:
        num = int(input("請輸入一個數:"))
        if 0<=num<=100:
            return num
        else:return 0 
    except ValueError:
        return 0
score = get_score()
print(score)

3、處理異常語句 try-except語句

3.1 語法:

try :
    可能觸發異常的語句
finally:
    最終語句

3.2 說明:

finally子句不可以省略
一定不存在except子句

3.3 作用:

通常用try-finally 語句來做觸發異常時必須要處理的事情,無論異常是否發生,finally字句都會執行
try-finally語句不會更改程式的(正常/異常狀態)

3.4 示例:

def fry_egg():
    print("開啟天然氣...")
    try:
        count = int(input("請輸入煎幾個雞蛋:"))
        print("完成煎雞蛋,共煎了%d個雞蛋"%count)
    finally:
        print("關閉天然氣...")
try:
    fry_egg()
except:
    print("程式出現異常,已轉為正常狀態")
print("程式正常退出")

4、try 語句巢狀示例

4.1 定義:try語句巢狀是指一個try語句巢狀在另一個try語句內使用

4.2 示例1

x = 100
y = 200
try:
    save_x = x
    save_y = y
    try:
        print('x = {},y = {}'.format(x,y))
        x = int(input("x="))
        y = int(input("y="))
        print("列印x y,列印完成後x,y恢復原值")
        print('’x = {},y = {}'.format(x,y))
    finally: 
        x = save_x
        y = save_y
finally:
    pass
print('x = {},y = {}'.format(x,y))

4.3 示例2

# 此示例示意try語句巢狀,在內層的try語句如果已經把狀態轉為正常狀態,則外層的try語句將收不到錯誤通知
try:
    try:
        n = int(input("請輸入整數:"))
    except ValueError:
        print("在內層try出現值錯誤,已轉為正常狀態")
    else:
        print("內層try沒有出現異常")
except:
    print("外層的try語句接到異常通知,已處理並轉為正常狀態")
else:
    print("外層的try語句沒有出現異常")

5、raise語句

5.1 作用:

觸發一個錯誤,讓程式進入異常狀態
傳送錯誤通知給呼叫者

5.2 語法:

raise 異常型別
或
raise 異常物件
或
raise  #重新出發上一次異常

5.3 示例1:

def make_except():
    print("開始")
    try:
        raise ValueError   # 故意傳送一個錯誤通知
    except:
        print("接到異常通知,已處理並轉為正常狀態")
    print("呼叫結束")
try:
    make_except()
except:
    print("接到異常通知,已處理並轉為正常狀態")
print("程式結束")

5.4 示例2

def make_except():
    print("開始")
    e = ValueError("這是一個故意製作的異常")
    raise e
    print("結束")
try:
    make_except()
except ValueError as err:
    print("接到異常通知,已處理並轉為正常狀態")
    # 獲取錯誤的原因
    print(err)
print("程式結束")

5.5 示例3

# 寫一個get_age()函式用來獲取一個人的年齡資訊
# 此函式規定與歐諾個戶只能輸入1~140之間的整數,如果輸入其他則直接出發ValueError錯誤型別來通知呼叫者
def get_age():
    age = int(input("請輸入年齡(1~140):"))
    if age >140 or age <1:
        raise ValueError("使用者輸入的不是1~140範圍內的數字,獲取年齡失敗!")
    else:
        return age
def main():
    try:
        age = get_age()
        print("使用者輸入的年齡是:",age)
    except ValueError as err:
        print("發生錯誤的型別為:",err)
main()

6、assert 語句(斷言語句)

6.1 語法:

assert 真值表達式,錯誤資料(通常是字串)

6.2 作用:

當真值表示式為Flase時,用錯誤資料建立一個AssertionError型別的錯誤raise出去,並進入異常狀態
等同於:
if 真值表達式 == Flase:
    raise AssertionError

6.3 示例:

# 此示例示意assert語句的用法
def get_score():
    s = int(input("請輸入學生成績(1~100):"))
    assert 0<=s<=100,'成績超出範圍!'
    return s
try:
    score = get_score()
    print("學生的成績為:",score)
except ValueError:
    print("輸入資料型別有誤!")
except AssertionError:
    print("使用者輸入的整數不在0~100之間!")