異常

1.1異常簡(jiǎn)介

異常就是程序運(yùn)行錯(cuò)誤或者邏輯混亂。需要給客戶友好的提示。

異常一般是程序中無法完全避免,一般通過一定的手段,盡量減少異常的發(fā)生。

看如下示例:

print'-----test--1---'

open('123.txt','r')

print('-----test--2---')

打開一個(gè)不存在的文件123.txt,當(dāng)找不到123.txt文件時(shí),就會(huì)拋出給我們一個(gè)IOError類型的錯(cuò)誤,No such file or directory:123.txt(沒有123.txt這樣的文件或目錄)

異常:

當(dāng)Python檢測(cè)到一個(gè)錯(cuò)誤時(shí),解釋器就無法繼續(xù)執(zhí)行了,反而出現(xiàn)了一些錯(cuò)誤的提示,這就是所謂的"異常"

1.1捕獲異常

1.1.1捕獲異常try...except...

看如下示例:

try:

print('-----test--1---')

open('123.txt','r')

print('-----test--2---')

exceptIOError:

pass

說明:

·此程序看不到任何錯(cuò)誤,因?yàn)橛胑xcept捕獲到了IOError異常,并添加了處理的方法

·pass表示實(shí)現(xiàn)了相應(yīng)的實(shí)現(xiàn),但什么也不做;如果把pass改為print語句,那么就會(huì)輸出其他信息

·把可能出現(xiàn)問題的代碼,放在try中

·把處理異常的代碼,放在except中

1.1.1except捕獲多個(gè)異常

看如下示例:

try:

printnum

exceptIOError:

print('產(chǎn)生錯(cuò)誤了')

運(yùn)行結(jié)果如下:

想一想:

上例程序,已經(jīng)使用except來捕獲異常了,為什么還會(huì)看到錯(cuò)誤的信息提示?

答:

except捕獲的錯(cuò)誤類型是IOError,而此時(shí)程序產(chǎn)生的異常為NameError,所以except沒有生效

修改后的代碼為:

try:

printnum

exceptNameError:

print('產(chǎn)生錯(cuò)誤了')

運(yùn)行結(jié)果如下:

實(shí)際開發(fā)中,捕獲多個(gè)異常的方式,如下:

#coding=utf-8

try:

print('-----test--1---')

open('123.txt','r')#如果123.txt文件不存在,那么會(huì)產(chǎn)生IOError異常

print('-----test--2---')

print(num)#如果num變量沒有定義,那么會(huì)產(chǎn)生NameError異常

except(IOError,NameError):

#如果想通過一次except捕獲到多個(gè)異常可以用一個(gè)元組的方式

# errorMsg里會(huì)保存捕獲到的錯(cuò)誤信息

print(errorMsg)

注意:

·當(dāng)捕獲多個(gè)異常時(shí),可以把要捕獲的異常的名字,放到except后,并使用元組的方式僅進(jìn)行存儲(chǔ)

1.1.1else

咱們應(yīng)該對(duì)else并不陌生,在if中,它的作用是當(dāng)條件不滿足時(shí)執(zhí)行的實(shí)行;同樣在try...except...中也是如此,即如果沒有捕獲到異常,那么就執(zhí)行else中的事情

try:

#num = 100

print(num)

except NameError as errorMsg:

print('產(chǎn)生錯(cuò)誤了:%s'%errorMsg)

else:

print('沒有捕獲到異常,真高興')

print('over...')

1.1.1try...finally...

try...finally...語句用來表達(dá)這樣的情況:

在程序中,如果一個(gè)段代碼必須要執(zhí)行,即無論異常是否產(chǎn)生都要執(zhí)行,那么此時(shí)就需要使用finally。 比如文件關(guān)閉,釋放鎖,把數(shù)據(jù)庫(kù)連接返還給連接池等

demo:

importtime

try:

f = open('test.txt')

try:

whileTrue:

content = f.readline()

iflen(content) ==0:

break

time.sleep(2)

print(content)

except:

#如果在讀取文件的過程中,產(chǎn)生了異常,那么就會(huì)捕獲到

#比如 按下了ctrl+c

pass

finally:

f.close()

print('關(guān)閉文件')

except:

print("沒有這個(gè)文件")

說明:

test.txt文件中每一行數(shù)據(jù)打印,但是我有意在每打印一行之前用time.sleep方法暫停2秒鐘。這樣做的原因是讓程序運(yùn)行得慢一些。在程序運(yùn)行的時(shí)候,按Ctrl+c中斷(取消)程序。

我們可以觀察到KeyboardInterrupt異常被觸發(fā),程序退出。但是在程序退出之前,finally從句仍然被執(zhí)行,把文件關(guān)閉。

1.1異常的傳遞

1.1.1try嵌套中

importtime

try:

f = open('test.txt')

try:

whileTrue:

content = f.readline()

iflen(content) ==0:

break

time.sleep(2)

print(content)

finally:

f.close()

print('關(guān)閉文件')

except:

print("沒有這個(gè)文件")

運(yùn)行結(jié)果:

In [26]: import time

...: try:

...: ????f = open('test.txt')

...: ????try:

...: ????????while True:

...: ????????????content = f.readline()

...: ????????????if len(content) == 0:

...: ????????????????break

...: ????????????time.sleep(2)

...: ????????????print(content)

...: ????finally:

...: ????????f.close()

...: ????????print('關(guān)閉文件')

...: except:

...: ????print("沒有這個(gè)文件")

...: finally:

...: ????print("最后的finally")

...:

xxxxxxx--->這是test.txt文件中讀取到信息

^C關(guān)閉文件

沒有這個(gè)文件

最后的finally

1.1.2函數(shù)嵌套調(diào)用中

deftest1():

print("----test1-1----")

print(num)

print("----test1-2----")

deftest2():

print("----test2-1----")

test1()

print("----test2-2----")

deftest3():

try:

print("----test3-1----")

test1()

print("----test3-2----")

exceptExceptionasresult:

print("捕獲到了異常,信息是:%s"%result)

print("----test3-2----")

test3()

print("------華麗的分割線-----")

test2()

總結(jié):

·如果try嵌套,那么如果里面的try沒有捕獲到這個(gè)異常,那么外面的try會(huì)接收到這個(gè)異常,然后進(jìn)行處理,如果外邊的try依然沒有捕獲到,那么再進(jìn)行傳遞。。。

·如果一個(gè)異常是在一個(gè)函數(shù)中產(chǎn)生的,例如函數(shù)A---->函數(shù)B---->函數(shù)C,而異常是在函數(shù)C中產(chǎn)生的,那么如果函數(shù)C中沒有對(duì)這個(gè)異常進(jìn)行處理,那么這個(gè)異常會(huì)傳遞到函數(shù)B中,如果函數(shù)B有異常處理那么就會(huì)按照函數(shù)B的處理方式進(jìn)行執(zhí)行;如果函數(shù)B也沒有異常處理,那么這個(gè)異常會(huì)繼續(xù)傳遞,以此類推。。。如果所有的函數(shù)都沒有處理,那么此時(shí)就會(huì)進(jìn)行異常的默認(rèn)處理,即通常見到的那樣

·注意觀察上圖中,當(dāng)調(diào)用test3函數(shù)時(shí),在test1函數(shù)內(nèi)部產(chǎn)生了異常,此異常被傳遞到test3函數(shù)中完成了異常處理,而當(dāng)異常處理完后,并沒有返回到函數(shù)test1中進(jìn)行執(zhí)行,而是在函數(shù)test3中繼續(xù)執(zhí)行

1.1拋出自定義的異常

你可以用raise語句來引發(fā)一個(gè)異常。異常/錯(cuò)誤對(duì)象必須有一個(gè)名字,且它們應(yīng)是Error或Exception類的子類

下面是一個(gè)引發(fā)異常的例子:

classShortInputException(Exception):

'''自定義的異常類'''

def__init__(self, length, atleast):

#super().__init__()

self.length = length

self.atleast = atleast

defmain():

try:

s = input('請(qǐng)輸入--> ')

iflen(s) <3:

# raise引發(fā)一個(gè)你定義的異常

raiseShortInputException(len(s),3)

exceptShortInputExceptionasresult:#x這個(gè)變量被綁定到了錯(cuò)誤的實(shí)例

print('ShortInputException:輸入的長(zhǎng)度是%d,長(zhǎng)度至少應(yīng)是%d'% (result.length, result.atleast))

else:

print('沒有異常發(fā)生.')

main()

注意

·以上程序中,關(guān)于代碼#super().__init__()的說明

這一行代碼,可以調(diào)用也可以不調(diào)用,建議調(diào)用,因?yàn)開_init__方法往往是用來對(duì)創(chuàng)建完的對(duì)象進(jìn)行初始化工作,如果在子類中重寫了父類的__init__方法,即意味著父類中的很多初始化工作沒有做,這樣就不保證程序的穩(wěn)定了,所以在以后的開發(fā)中,如果重寫了父類的__init__方法,最好是先調(diào)用父類的這個(gè)方法,然后再添加自己的功能

1.1異常處理中拋出異常

classTest(object):

def__init__(self, switch):

self.switch = switch#開關(guān)

defcalc(self, a, b):

try:

returna/b

exceptExceptionasresult:

ifself.switch:

print("捕獲開啟,已經(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)

20P????{

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1異常 1.1異常簡(jiǎn)介 異常就是程序運(yùn)行錯(cuò)誤或者邏輯混亂。不能讓用戶看到直接代碼的報(bào)錯(cuò),需要給客戶友好的提示。 異...
    步_塵閱讀 604評(píng)論 0 0
  • 1異常 1.1異常簡(jiǎn)介 異常就是程序運(yùn)行錯(cuò)誤或者邏輯混亂。需要給客戶友好的提示。 異常一般是程序中無法完全避免,一...
    西多的大叔閱讀 835評(píng)論 0 0
  • 1異常 1.1異常簡(jiǎn)介 異常就是程序運(yùn)行錯(cuò)誤或者邏輯混亂。不能讓用戶看到直接代碼的報(bào)錯(cuò),需要給客戶友好的提示。 異...
    冬gua閱讀 249評(píng)論 0 0
  • 有一個(gè)色盲,雨后在湖邊散步,他看到天空出現(xiàn)一道彩虹,并作詩(shī)自吟道:“灰色的彩虹,高高地掛在天空……?!边@時(shí),旁邊路...
    海王星1984閱讀 437評(píng)論 0 0
  • 今天我們班團(tuán)風(fēng)采,本來說好的寢室三個(gè)人都參加,后來我和六日因?yàn)榈谝淮螞]去排練就懶惰了。這幾天紅紅為排練也付出了很多...
    娛樂機(jī)閱讀 139評(píng)論 0 0

友情鏈接更多精彩內(nèi)容