1.1.異常的概念
- 程序在運(yùn)行時(shí),如果python解釋器遇到一個(gè)錯(cuò)誤,會(huì)停止程序的運(yùn)行,并且提示一些錯(cuò)誤信息,這就是異常
- 程序停止執(zhí)行并且提示錯(cuò)誤信息后這個(gè)動(dòng)作,我們通常稱之為:拋出異常
程序開(kāi)發(fā)時(shí),很難將所有的特殊情況都處理的面面俱到,通過(guò)異常捕獲可以針對(duì)突發(fā)事件做集中的處理,從而保證程序的穩(wěn)定性和健壯性
一段代碼:
num = int(input("請(qǐng)輸入數(shù)字:"))
print('hello')
如果我們輸入非數(shù)字,輸出:
請(qǐng)輸入數(shù)字:s
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/untitled16/ex.py", line 6, in <module>
num = int(input("請(qǐng)輸入數(shù)字:"))
ValueError: invalid literal for int() with base 10: 's'
1.發(fā)生錯(cuò)誤2.程序終止---hello沒(méi)有輸出
1.2.捕獲異常
1.2.1.簡(jiǎn)單的捕獲異常語(yǔ)法
- 在程序開(kāi)發(fā)中,如果對(duì)某些代碼的執(zhí)行不能確定是否正確,可以增加try(嘗試)來(lái)捕獲異常
- 捕獲異常最常見(jiàn)的語(yǔ)法格式:
try:
嘗試執(zhí)行的代碼
except:
出現(xiàn)錯(cuò)誤的處理
- try 嘗試,下方編寫(xiě)要嘗試代碼,不確定是否能夠正常執(zhí)行的代碼
- except 如果不是,下方編寫(xiě)嘗試失敗的代碼
簡(jiǎn)單異常捕獲演練--要求用戶輸入整數(shù)
try:
#提示用戶輸入一個(gè)數(shù)字
num = int(input("請(qǐng)輸入數(shù)字:"))
except:
print("請(qǐng)輸入正確的數(shù)字")
print('hello')
輸入非數(shù)字:
請(qǐng)輸入數(shù)字: r
請(qǐng)輸入正確的數(shù)字
hello
程序沒(méi)有終止,輸出了hello
1.2.2.錯(cuò)誤類(lèi)型捕獲
- 在程序執(zhí)行時(shí),可能會(huì)遇到不同類(lèi)型的異常,并且需要針對(duì)不同類(lèi)型的異常,做出不同的響應(yīng),這個(gè)時(shí)候,就需要捕獲錯(cuò)誤類(lèi)型了
- 語(yǔ)法如下:
try:
#嘗試執(zhí)行的代碼
pass
except 錯(cuò)誤類(lèi)型1:
#針對(duì)錯(cuò)誤類(lèi)型1,對(duì)應(yīng)的代碼處理
pass
except (錯(cuò)誤類(lèi)型2,錯(cuò)誤類(lèi)型3):
#針對(duì)錯(cuò)誤類(lèi)型2和3,對(duì)應(yīng)的代碼處理
pass
except Exception as result:
print("未知錯(cuò)誤 %s" % result)
- 當(dāng)python解釋器拋出異常時(shí),最后一行錯(cuò)誤信息的第一個(gè)單詞,就是錯(cuò)誤類(lèi)型
異常類(lèi)型捕獲演練--要求用戶輸入整數(shù)
需求
1.提示用戶輸入一個(gè)整數(shù)
2.使用8除以用戶輸入的整數(shù)并且輸出
try:
num = int(input("請(qǐng)輸入整數(shù):"))
result = 8 / num
print(result)
except ValueError:
print("請(qǐng)輸入正確的整數(shù)")
except ZeroDivisionError:
print("除0錯(cuò)誤")
捕獲未知錯(cuò)誤
- 在開(kāi)發(fā)時(shí),要預(yù)判到所有可能出現(xiàn)的錯(cuò)誤,還是有一定難度的
- 如果希望程序無(wú)論出現(xiàn)任何錯(cuò)誤,都不會(huì)因?yàn)閜ython解釋器拋出異常而被終止,可以再增加一個(gè)except
語(yǔ)法如下:
except Exception as result:
print("未知錯(cuò)誤 %s" % result)
1.2.3.異常捕獲完整語(yǔ)法
- 在實(shí)際開(kāi)發(fā)中,為了能夠處理復(fù)雜的異常情況,完整的異常語(yǔ)法如下:
提示: - 有關(guān)完整語(yǔ)法的應(yīng)用場(chǎng)景,在后續(xù)學(xué)習(xí)中,結(jié)合實(shí)際的案例會(huì)更好理解
- 現(xiàn)在先對(duì)這個(gè)語(yǔ)法結(jié)構(gòu)有個(gè)印象即可
try:
# 嘗試執(zhí)行的代碼
pass
except 錯(cuò)誤類(lèi)型1:
# 針對(duì)錯(cuò)誤類(lèi)型1,對(duì)應(yīng)的代碼處理
pass
except 錯(cuò)誤類(lèi)型2:
# 針對(duì)錯(cuò)誤類(lèi)型2,對(duì)應(yīng)的代碼處理
pass
except (錯(cuò)誤類(lèi)型3, 錯(cuò)誤類(lèi)型4):
# 針對(duì)錯(cuò)誤類(lèi)型3 和 4,對(duì)應(yīng)的代碼處理
pass
except Exception as result:
# 打印錯(cuò)誤信息
print(result)
else:
# 沒(méi)有異常才會(huì)執(zhí)行的代碼
pass
finally:
# 無(wú)論是否有異常,都會(huì)執(zhí)行的代碼
print("無(wú)論是否有異常,都會(huì)執(zhí)行的代碼")
- else只有在沒(méi)有異常時(shí)才會(huì)執(zhí)行的代碼
- finally無(wú)論是否有異常,都會(huì)執(zhí)行的代碼
- 之前一個(gè)演練的完整捕獲異常的代碼如下:
try:
num = int(input("請(qǐng)輸入整數(shù):"))
result = 8 / num
print(result)
except ValueError:
print("請(qǐng)輸入正確的整數(shù)")
except ZeroDivisionError:
print("除0錯(cuò)誤")
except Exception as result:
print("未知錯(cuò)誤 %s" % result)
else:
print("正常執(zhí)行")
finally:
print("執(zhí)行完成,但是不保證正確")
1.3.異常處理
- 異常的傳遞--當(dāng)函數(shù)/方法執(zhí)行出現(xiàn)異常,會(huì)將異常傳遞給函數(shù)/方法的調(diào)用一方
- 如果傳遞到主程序,仍然沒(méi)有異常處理,程序才會(huì)被終止
提示: - 在開(kāi)發(fā)中,可以在主函數(shù)中增加異常捕獲
- 而在主函數(shù)中調(diào)用的其他函數(shù),只要出現(xiàn)異常,都會(huì)傳遞到主函數(shù)的異常捕獲中
- 這樣就不需要在代碼中,增加大量的異常捕獲,能夠保證代碼的癥結(jié)
需求:
1.定義函數(shù)demo1()提示用戶輸入一個(gè)整數(shù)并且返回
2.定義函數(shù)demo2()調(diào)用demo1()
3.在主程序中調(diào)用demo2()
def demo1():
return int(input("請(qǐng)輸入一個(gè)整數(shù):"))
def demo2():
return demo1()
try:
print(demo2())
except ValueError:
print("請(qǐng)輸入正確的整數(shù)")
except Exception as resutlt:
print("未知錯(cuò)誤 %s" % result)
1.4.拋出raise異常
1.4.1.應(yīng)用場(chǎng)景
- 在開(kāi)發(fā)中,除了代碼執(zhí)行出錯(cuò)python解釋器會(huì)拋出異常之外,還可以根據(jù)應(yīng)用程序特有的業(yè)務(wù)需求主動(dòng)拋出異常
示例 - 提示用戶輸入密碼,如果長(zhǎng)度小于8,拋出異常
注意 - 當(dāng)前函數(shù)只負(fù)責(zé)提示提示用戶名輸入密碼,如果密碼長(zhǎng)度不正確,需要其他的函數(shù)進(jìn)行額外處理
- 因此可以拋出異常,由其他需要處理的函數(shù)捕獲異常
1.4.2.拋出異常
- python中提供了一個(gè)Exception異常類(lèi)
- 在開(kāi)發(fā)中,如果滿足特定業(yè)務(wù)需求時(shí),希望拋出異常,可以:
1.創(chuàng)建一個(gè)Exception的對(duì)象
2.使用raise關(guān)鍵字拋出一場(chǎng)對(duì)象
需求 - 定義input_password函數(shù),提示用戶輸入密碼
- 如果用戶輸入長(zhǎng)度<8,拋出異常
- 如果用戶輸入長(zhǎng)度>=8,返回輸入的密碼
def input_password():
#1\.提示用戶輸入密碼
pwd = input("請(qǐng)輸入密碼:")
#2\.判斷密碼長(zhǎng)度,如果長(zhǎng)度>=8,返回用戶輸入的密碼
if len(pwd) >= 8:
return pwd
#3\.密碼長(zhǎng)度不夠,需要拋出異常
#1>創(chuàng)建異常對(duì)象-使用異常的錯(cuò)誤信息字符串作為參數(shù)
ex = Exception("密碼長(zhǎng)度不夠")
#2>拋出異常對(duì)象
raise ex
try:
user_pwd = input_password()
print(user_pwd)
except Exception as result:
print("發(fā)現(xiàn)錯(cuò)誤:%s" % result)
1.5.自定義異常
自定義異常主要是自己定義的異常類(lèi),對(duì)異常進(jìn)行分門(mén)別類(lèi)管理,自定義異常需要繼承異常父類(lèi)Exception一個(gè)例子
class MyException(Exception): #讓MyException類(lèi)繼承Exception
def __init__(self,name,age):
self.name = name
self.age = age
try:
#知識(shí)點(diǎn):主動(dòng)拋出異常,就是實(shí)例化一個(gè)異常類(lèi)
raise MyException("zhangsan",19) #實(shí)例化一個(gè)異常,實(shí)例化的時(shí)候需要傳參數(shù)
except MyException as obj: #這里體現(xiàn)一個(gè)封裝
print(obj.age,obj.name) #捕獲的就是MyException類(lèi)攜帶過(guò)來(lái)的信息
except Exception as obj: #萬(wàn)能捕獲,之前的可能捕獲不到,這里添加Excetpin
print(obj)