本節(jié)課綱:
- 異常的概念
- 捕獲異常
- 異常的傳遞
- 拋出raise異常
- 自定義異常
一、異常的概念
- 程序在運行時,如果 Python 解釋器 遇到 到一個錯誤宰缤,會停止程序的執(zhí)行,并且提示一些錯誤信息晃洒,這就是 異常
- 程序停止執(zhí)行并且提示錯誤信息 這個動作慨灭,我們通常稱之為:拋出(raise)異常
程序開發(fā)時,很難將 所有的特殊情況 都處理的面面俱到球及,通過 異常捕獲 可以針對突發(fā)事件做集中的處理氧骤,從而保證程序的 穩(wěn)定性和健壯性
一段代碼:
num = int(input("請輸入數(shù)字:"))
print('hello')
如果我們輸入非數(shù)字,輸出:
請輸入數(shù)字:s
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/untitled16/ex.py", line 6, in <module>
num = int(input("請輸入數(shù)字:"))
ValueError: invalid literal for int() with base 10: 's'
1.發(fā)生錯誤 2.程序終止---hello沒有輸出
二、捕獲異常
2.1 簡單的捕獲異常語法
- 在程序開發(fā)中吃引,如果 對某些代碼的執(zhí)行不能確定是否正確筹陵,可以增加 try(嘗試) 來 捕獲異常
- 捕獲異常最簡單的語法格式:
try:
嘗試執(zhí)行的代碼
except:
出現(xiàn)錯誤的處理
- try 嘗試,下方編寫要嘗試代碼镊尺,不確定是否能夠正常執(zhí)行的代碼
- except 如果不是朦佩,下方編寫嘗試失敗的代碼
簡單異常捕獲演練 —— 要求用戶輸入整數(shù)
try:
# 提示用戶輸入一個數(shù)字
num = int(input("請輸入數(shù)字:"))
except:
print("請輸入正確的數(shù)字")
print('hello')
輸入非數(shù)字:
請輸入數(shù)字:r
請輸入正確的數(shù)字
hello
程序沒有終止,輸出了hello
2.2 錯誤類型捕獲
在程序執(zhí)行時鹅心,可能會遇到 不同類型的異常吕粗,并且需要 針對不同類型的異常,做出不同的響應旭愧,這個時候颅筋,就需要捕獲錯誤類型了
語法如下:
try:
# 嘗試執(zhí)行的代碼
pass
except 錯誤類型1:
# 針對錯誤類型1,對應的代碼處理
pass
except (錯誤類型2, 錯誤類型3):
# 針對錯誤類型2 和 3输枯,對應的代碼處理
pass
except Exception as result:
print("未知錯誤 %s" % result)
- 當 Python 解釋器 拋出異常 時议泵,最后一行錯誤信息的第一個單詞,就是錯誤類型
異常類型捕獲演練 —— 要求用戶輸入整數(shù)
需求
1)提示用戶輸入一個整數(shù)
2)使用 8 除以用戶輸入的整數(shù)并且輸出
try:
num = int(input("請輸入整數(shù):"))
result = 8 / num
print(result)
except ValueError:
print("請輸入正確的整數(shù)")
except ZeroDivisionError:
print("除 0 錯誤")
捕獲未知錯誤
- 在開發(fā)時桃熄,要預判到所有可能出現(xiàn)的錯誤先口,還是有一定難度的
- 如果希望程序 無論出現(xiàn)任何錯誤,都不會因為 Python 解釋器 拋出異常而被終止瞳收,可以再增加一個 except
語法如下:
except Exception as result:
print("未知錯誤 %s" % result)
2.3 異常捕獲完整語
- 在實際開發(fā)中碉京,為了能夠處理復雜的異常情況,完整的異常語法如下:
提示:
1)有關完整語法的應用場景螟深,在后續(xù)學習中谐宙,結合實際的案例會更好理解
2)現(xiàn)在先對這個語法結構有個印象即可
try:
# 嘗試執(zhí)行的代碼
pass
except 錯誤類型1:
# 針對錯誤類型1,對應的代碼處理
pass
except 錯誤類型2:
# 針對錯誤類型2界弧,對應的代碼處理
pass
except (錯誤類型3, 錯誤類型4):
# 針對錯誤類型3 和 4凡蜻,對應的代碼處理
pass
except Exception as result:
# 打印錯誤信息
print(result)
else:
# 沒有異常才會執(zhí)行的代碼
pass
finally:
# 無論是否有異常搭综,都會執(zhí)行的代碼
print("無論是否有異常,都會執(zhí)行的代碼")
else 只有在沒有異常時才會執(zhí)行的代碼
finally 無論是否有異常划栓,都會執(zhí)行的代碼
之前一個演練的 完整捕獲異常 的代碼如下:
try:
num = int(input("請輸入整數(shù):"))
result = 8 / num
print(result)
except ValueError:
print("請輸入正確的整數(shù)")
except ZeroDivisionError:
print("除 0 錯誤")
except Exception as result:
print("未知錯誤 %s" % result)
else:
print("正常執(zhí)行")
finally:
print("執(zhí)行完成兑巾,但是不保證正確")
三、異常的傳遞
- 異常的傳遞 —— 當 函數(shù)/方法 執(zhí)行 出現(xiàn)異常忠荞,會 將異常傳遞 給 函數(shù)/方法 的 調用一方
- 如果 傳遞到主程序蒋歌,仍然 沒有異常處理,程序才會被終止
提示
- 在開發(fā)中钻洒,可以在主函數(shù)中增加 異常捕獲
- 而在主函數(shù)中調用的其他函數(shù)奋姿,只要出現(xiàn)異常,都會傳遞到主函數(shù)的 異常捕獲 中
- 這樣就不需要在代碼中素标,增加大量的 異常捕獲称诗,能夠保證代碼的整潔
需求
1.定義函數(shù) demo1() 提示用戶輸入一個整數(shù)并且返回
2.定義函數(shù) demo2() 調用 demo1()
3.在主程序中調用 demo2()
def demo1():
return int(input("請輸入一個整數(shù):"))
def demo2():
return demo1()
try:
print(demo2())
except ValueError:
print("請輸入正確的整數(shù)")
except Exception as result:
print("未知錯誤 %s" % result)
四、拋出raise異常
4.1 應用場景
- 在開發(fā)中头遭,除了 代碼執(zhí)行出錯 Python 解釋器會 拋出 異常之外
- 還可以根據 應用程序 特有的業(yè)務需求 主動拋出異常
示例
- 提示用戶 輸入密碼寓免,如果 長度少于 8,拋出 異常
注意 - 當前函數(shù) 只負責 提示用戶輸入密碼计维,如果 密碼長度不正確袜香,需要其他的函數(shù)進行額外處理
- 因此可以 拋出異常,由其他需要處理的函數(shù) 捕獲異常
4.2 拋出異常
- Python 中提供了一個 Exception 異常類
- 在開發(fā)時鲫惶,如果滿足 特定業(yè)務需求時蜈首,希望 拋出異常,可以:
1.創(chuàng)建 一個 Exception 的 對象
2.使用 raise 關鍵字 拋出 異常對象
需求
- 定義 input_password 函數(shù)欠母,提示用戶輸入密碼
- 如果用戶輸入長度 < 8欢策,拋出異常
- 如果用戶輸入長度 >=8,返回輸入的密碼
def input_password():
# 1\. 提示用戶輸入密碼
pwd = input("請輸入密碼:")
# 2\. 判斷密碼長度赏淌,如果長度 >= 8踩寇,返回用戶輸入的密碼
if len(pwd) >= 8:
return pwd
# 3\. 密碼長度不夠,需要拋出異常
# 1> 創(chuàng)建異常對象 - 使用異常的錯誤信息字符串作為參數(shù)
ex = Exception("密碼長度不夠")
# 2> 拋出異常對象
raise ex
try:
user_pwd = input_password()
print(user_pwd)
except Exception as result:
print("發(fā)現(xiàn)錯誤:%s" % result)
五六水、自定義異常
自定義異常主要是自己定義的異常類俺孙,對異常進行分門別類管理,自定義異常需要繼承異常父類Exception 一個例子
class MyException(Exception): #讓MyException類繼承Exception
def __init__(self,name,age):
self.name = name
self.age = age
try:
#知識點:主動拋出異常掷贾,就是實例化一個異常類
raise MyException("zhansgan",19) #實例化一個異常,實例化的時候需要傳參數(shù)
except MyException as obj: #這里體現(xiàn)一個封裝睛榄,
print(obj.age,obj.name) #捕獲的就是MyException類攜帶過來的信息
except Exception as obj: #萬能捕獲,之前的可能捕獲不到想帅,這里添加Exception作為保底
print(obj)