一篇文章帶你弄懂Python異常傳遞和自定義異常
一、異常的傳遞
1. try嵌套中
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
finally:
f.close()
print('關(guān)閉文件')
except :
print("沒(méi)有這個(gè)文件")
finally:
print("最后的finally")
# 這是test.txt文件中讀取到信息
運(yùn)行結(jié)果:
2. 函數(shù)嵌套調(diào)用中
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 result:
print("捕獲到了異常,信息是:%s"%result)
print("----test3-2----")
test3()
print("------華麗的分割線-----")
test2()
運(yùn)行結(jié)果:
小總結(jié):
- 如果try嵌套,那么如果里面的try沒(méi)有捕獲到這個(gè)異常,那么外面的try會(huì)接收到這個(gè)異常,然后進(jìn)行處理,如果外邊的try依然沒(méi)有捕獲到,那么再進(jìn)行傳遞。
- 如果一個(gè)異常是在一個(gè)函數(shù)中產(chǎn)生的,例如函數(shù)A---->函數(shù)B---->函數(shù)C,而異常是在函數(shù)C中產(chǎn)生的,那么如果函數(shù)C中沒(méi)有對(duì)這個(gè)異常進(jìn)行處理,那么這個(gè)異常會(huì)傳遞到函數(shù)B中,如果函數(shù)B有異常處理那么就會(huì)按照函數(shù)B的處理方式進(jìn)行執(zhí)行;如果函數(shù)B也沒(méi)有異常處理,那么這個(gè)異常會(huì)繼續(xù)傳遞,以此類(lèi)推。。。如果所有的函數(shù)都沒(méi)有處理,那么此時(shí)就會(huì)進(jìn)行異常的默認(rèn)處理。
二、拋出自定義的異常
你可以用raise語(yǔ)句來(lái)引發(fā)一個(gè)異常。異常/錯(cuò)誤對(duì)象必須有一個(gè)名字,且它們應(yīng)是Error或Exception類(lèi)的子類(lèi)
下面是一個(gè)引發(fā)異常的例子:
class ShortInputException(Exception):
'''自定義的異常類(lèi)'''
def __init__(self, length, atleast):
#super().__init__()
self.length = length
self.atleast = atleast
def main():
try:
s = input('請(qǐng)輸入 --> ')
if len(s) < 3:
# raise引發(fā)一個(gè)你定義的異常
raise ShortInputException(len(s), 3) #自定義異常長(zhǎng)度為3。
except ShortInputException as result:#x這個(gè)變量被綁定到了錯(cuò)誤的實(shí)例
print('ShortInputException: 輸入的長(zhǎng)度是 %d,長(zhǎng)度至少應(yīng)是 %d'% (result.length, result.atleast))
else:
print('沒(méi)有異常發(fā)生.')
main()
運(yùn)行結(jié)果:
以上程序中,關(guān)于#super().init()代碼的說(shuō)明:
這一行代碼,可以調(diào)用也可以不調(diào)用,建議調(diào)用。
因?yàn)開(kāi)_init__方法往往是用來(lái)對(duì)創(chuàng)建完的對(duì)象進(jìn)行初始化工作,如果在子類(lèi)中重寫(xiě)了父類(lèi)的__init__方法,即意味著父類(lèi)中的很多初始化工作沒(méi)有做,這樣就不保證程序的穩(wěn)定了,所以在以后的開(kāi)發(fā)中,如果重寫(xiě)了父類(lèi)的__init__方法,最好是先調(diào)用父類(lèi)的這個(gè)方法,然后再添加自己的功能。
三、異常處理中拋出異常
class Test(object):
def __init__(self, switch):
self.switch = switch #開(kāi)關(guān)
def calc(self, a, b):
try:
return a/b
except Exception as result:
if self.switch:
print("捕獲開(kāi)啟,已經(jīng)捕獲到了異常,信息如下:")
print(result)
else:
#重新拋出這個(gè)異常,此時(shí)就不會(huì)被這個(gè)異常處理給捕獲到,從而觸發(fā)默認(rèn)的異常處理
raise
a = Test(True)
a.calc(11,0)
print("----------------------華麗的分割線----------------")
a.switch = False
a.calc(11,0)
運(yùn)行結(jié)果:
四、總結(jié)
本文基于Python基礎(chǔ),詳細(xì)的講解了運(yùn)行過(guò)程中遇到各種異常,應(yīng)該采取什么樣的處理方式,對(duì)各種異常提供有效的解決方案。通過(guò)一個(gè)個(gè)小項(xiàng)目實(shí)際操作,運(yùn)行結(jié)果展示,能夠更好的解決問(wèn)題。希望可以幫助你更好的學(xué)習(xí)Python。