Python中的異常怎么處理?
一、異常介紹
print("1---------------------")
open("123.txt","r")
print("2---------------------")
運行結(jié)果為:
1---------------------
Traceback (most recent call last):
File "C:\Users\Se7eN_HOU\Desktop\demo.py", line 2, in
open("123.txt","r")
FileNotFoundError: [Errno 2] No such file or directory: '123.txt'
說明:打開一個不存在的文件123.txt,當(dāng)找不到123.txt 文件時,就會拋出給我們一個IOError類型的錯誤,No such file or directory:123.txt (沒有123.txt這樣的文件或目錄)
異常:當(dāng)Python檢測到一個錯誤時,解釋器就無法繼續(xù)執(zhí)行了,反而出現(xiàn)了一些錯誤的提示,這就是所謂的”異!薄
二、捕獲異常
try…except…
try:
print("1---------------------")
open("123.txt","r")
print("2---------------------")
except IOError:
pass
運行結(jié)果為:
1---------------------
說明:
1.此程序看不到任何錯誤,因為用except 捕獲到了IOError異常,并添加了處理的方法。
2.pass 表示實現(xiàn)了相應(yīng)的實現(xiàn),但什么也不做;如果把pass改為print語句,那么就會輸出其他信息。
3.把可能出現(xiàn)問題的代碼,放在try中。
4.把處理異常的代碼,放在except中。
三、except捕獲多個異常
try:
print(num)
except IOError:
print("產(chǎn)生的錯誤")
運行結(jié)果為:
Traceback (most recent call last):
File "C:\Users\Se7eN_HOU\Desktop\Tools\sublimetext3\Sublime Text Build 3176 x86\demo.py", line 2, in
print(num)
NameError: name 'num' is not defined
上例程序,已經(jīng)使用except來捕獲異常了,為什么還會看到錯誤的信息提示?因為:except捕獲的錯誤類型是IOError,而此時程序產(chǎn)生的異常為 NameError ,所以except沒有生效。
修改后的代碼為:
try:
print(num)
except NameError:
print("產(chǎn)生的錯誤")
運行結(jié)果為:
產(chǎn)生的錯誤
實際開發(fā)中,捕獲多個異常的方式,如下:
try:
print("1---------------------")
open("123.txt","r")
print("2---------------------")
print(num)
except (IOError,NameError):
print("產(chǎn)生的錯誤")
運行結(jié)果為:
1---------------------
產(chǎn)生的錯誤
當(dāng)捕獲多個異常時,可以把要捕獲的異常的名字,放到except 后,并使用元組的方式僅進(jìn)行存儲。
四、獲取異常的信息描述
try:
print("1---------------------")
open("123.txt","r")
print("2---------------------")
except Exception as e:#Exception是異常類,e是捕獲到的異常
print(e)
運行結(jié)果為:
1---------------------
[Errno 2] No such file or directory: '123.txt'
五、else
在if中,else的作用是當(dāng)條件不滿足時執(zhí)行的實行;同樣在try…except…中也是如此,即如果沒有捕獲到異常,那么就執(zhí)行else中的事情。
try:
num = 100
except Exception as e:#Exception是異常類,e是捕獲到的異常
print("產(chǎn)生錯位了:%s"%e)
else:
print("沒有捕獲異常,真高興")
運行結(jié)果為:
沒有捕獲異常,真高興
六、try…finally…
在程序中,如果一個段代碼必須要執(zhí)行,即無論異常是否產(chǎn)生都要執(zhí)行,那么此時就需要使用finally。 比如文件關(guān)閉,釋放鎖,把數(shù)據(jù)庫連接返還給連接池等。
import time
try:
f = open("test.txt")
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
except :
#如果再讀取文件的過程中,產(chǎn)生了異常,那么就會捕獲到
#比如 按下 ctrl + c
pass
finally:
f.close()
print("關(guān)閉文件")
except :
print("沒有這個文件")
test.txt文件中每一行數(shù)據(jù)打印,但是我有意在每打印一行之前用time.sleep方法暫停2秒鐘。這樣做的原因是讓程序運行得慢一些。在程序運行的時候,按Ctrl+c中斷(取消)程序。
我們可以觀察到KeyboardInterrupt異常被觸發(fā),程序退出。但是在程序退出之前,finally從句仍然被執(zhí)行,把文件關(guān)閉。
七、異常的傳遞
def test1():
print("------test1-1-------")
print(num)
print("------test1-2-------")
def test2():
print("------test2-1-------")
test1()
print("------test2-2-------")
def test3():
try:
print("------test3-1-------")
test1()
print("------test3-2-------")
except Exception as e:
print("捕獲到了異常,信息是:%s"%e)
test3()
print("--------------------------------------")
test2()
運行結(jié)果為:
------test3-1-------
------test1-1-------
捕獲到了異常,信息是:name 'num' is not defined
--------------------------------------
------test2-1-------
------test1-1-------
Traceback (most recent call last):
File "C:\Users\Se7eN_HOU\Desktop\Tools\sublimetext3\Sublime Text Build 3176 x86\demo.py", line 21, in
test2()
File "C:\Users\Se7eN_HOU\Desktop\Tools\sublimetext3\Sublime Text Build 3176 x86\demo.py", line 8, in test2
test1()
File "C:\Users\Se7eN_HOU\Desktop\Tools\sublimetext3\Sublime Text Build 3176 x86\demo.py", line 3, in test1
print(num)
NameError: name 'num' is not defined
如果try嵌套,那么如果里面的try沒有捕獲到這個異常,那么外面的try會接收到這個異常,然后進(jìn)行處理,如果外邊的try依然沒有捕獲到,那么再進(jìn)行傳遞。。。
如果一個異常是在一個函數(shù)中產(chǎn)生的,例如函數(shù)A—->函數(shù)B—->函數(shù)C,而異常是在函數(shù)C中產(chǎn)生的,那么如果函數(shù)C中沒有對這個異常進(jìn)行處理,那么這個異常會傳遞到函數(shù)B中,如果函數(shù)B有異常處理那么就會按照函數(shù)B的處理方式進(jìn)行執(zhí)行;如果函數(shù)B也沒有異常處理,那么這個異常會繼續(xù)傳遞,以此類推。。。如果所有的函數(shù)都沒有處理,那么此時就會進(jìn)行異常的默認(rèn)處理,即通常見到的那樣。
注意觀察上圖中,當(dāng)調(diào)用test3函數(shù)時,在test1函數(shù)內(nèi)部產(chǎn)生了異常,此異常被傳遞到test3函數(shù)中完成了異常處理,而當(dāng)異常處理完后,并沒有返回到函數(shù)test1中進(jìn)行執(zhí)行,而是在函數(shù)test3中繼續(xù)執(zhí)行。
八、拋出自定義的異常
用raise語句來引發(fā)一個異常。異常/錯誤對象必須有一個名字,且它們應(yīng)是Error或Exception類的子類。
class ShortInputException(Exception):
def __init__(self,length,atleast):
self.length = length
self.atleast = atleast
def main():
try:
s = input("請輸入:")
if len(s)<3:
raise ShortInputException(len(s),3)
except ShortInputException as e:
print("ShortInputException:輸入的長度是%d,長度至少是%d"%(e.length,e.atleast))
else:
print("沒有發(fā)生異常")
main()
運行結(jié)果為:
請輸入:qw
ShortInputException:輸入的長度是2,長度至少是3
請輸入:qwert
沒有發(fā)生異常
上一篇:python中如何引入包?
初級會計職稱中級會計職稱經(jīng)濟(jì)師注冊會計師證券從業(yè)銀行從業(yè)會計實操統(tǒng)計師審計師高級會計師基金從業(yè)資格稅務(wù)師資產(chǎn)評估師國際內(nèi)審師ACCA/CAT價格鑒證師統(tǒng)計資格從業(yè)
一級建造師二級建造師消防工程師造價工程師土建職稱房地產(chǎn)經(jīng)紀(jì)人公路檢測工程師建筑八大員注冊建筑師二級造價師監(jiān)理工程師咨詢工程師房地產(chǎn)估價師 城鄉(xiāng)規(guī)劃師結(jié)構(gòu)工程師巖土工程師安全工程師設(shè)備監(jiān)理師環(huán)境影響評價土地登記代理公路造價師公路監(jiān)理師化工工程師暖通工程師給排水工程師計量工程師
人力資源考試教師資格考試出版專業(yè)資格健康管理師導(dǎo)游考試社會工作者司法考試職稱計算機營養(yǎng)師心理咨詢師育嬰師事業(yè)單位教師招聘公務(wù)員公選考試招警考試選調(diào)生村官
執(zhí)業(yè)藥師執(zhí)業(yè)醫(yī)師衛(wèi)生資格考試衛(wèi)生高級職稱護(hù)士資格證初級護(hù)師主管護(hù)師住院醫(yī)師臨床執(zhí)業(yè)醫(yī)師臨床助理醫(yī)師中醫(yī)執(zhí)業(yè)醫(yī)師中醫(yī)助理醫(yī)師中西醫(yī)醫(yī)師中西醫(yī)助理口腔執(zhí)業(yè)醫(yī)師口腔助理醫(yī)師公共衛(wèi)生醫(yī)師公衛(wèi)助理醫(yī)師實踐技能內(nèi)科主治醫(yī)師外科主治醫(yī)師中醫(yī)內(nèi)科主治兒科主治醫(yī)師婦產(chǎn)科醫(yī)師西藥士/師中藥士/師臨床檢驗技師臨床醫(yī)學(xué)理論中醫(yī)理論