python如何主動(dòng)拋出異常和捕獲異常
1. 如何拋出異常?
異常的產(chǎn)生有兩種來源:
一種是程序自動(dòng)拋出,比如 1/0
會(huì)自動(dòng)拋出 ZeroDivisionError
一種是開發(fā)者主動(dòng)拋出,使用 raise
關(guān)鍵字拋出。
在 Python 中是使用 raise
關(guān)鍵字來拋出異常的,比如在下面這個(gè)函數(shù)中,如果不存在目標(biāo)文件,則會(huì)拋出一個(gè) Exception 通用異常。
def demo_func(filename):
if not os.path.isfile(filename):
raise Exception
2. 如何捕獲異常?
出現(xiàn)錯(cuò)誤或者異常沒有關(guān)系,關(guān)鍵在于你要學(xué)會(huì)預(yù)判程序可能會(huì)出現(xiàn)的錯(cuò)誤或異常,然后在代碼中捕獲這些異常并處理。
異常的捕獲的語法有如下四種:
第一種語法
只捕捉但是不想獲取異常信息
try:
代碼A
except [EXCEPTION]:
代碼B
第二種語法
不但捕捉了還要獲取異常信息,賦值給 e 后,后面你可以把異常信息打印到日志中。
try:
代碼A
except [EXCEPTION] as e:
代碼B
第三種語法
使用 try ... except ... else
如果代碼A發(fā)生了異常,則會(huì)走到代碼B的邏輯,如果沒有發(fā)生異常,則會(huì)走到代碼C
try:
代碼A
except [exception] as e:
代碼B
else:
代碼C
舉個(gè)例子
不發(fā)生異常的情況
>>> try:
... 4/2
... except ZeroDivisionError as e:
... print("發(fā)生了異常:錯(cuò)誤信息如下: \n" + str(e))
... else:
... print("程序正常運(yùn)行")
...
2
程序正常運(yùn)行
發(fā)生異常的情況
>>> try:
... 1/0
... except ZeroDivisionError as e:
... print("發(fā)生了異常:錯(cuò)誤信息如下: \n" + str(e))
... else:
... print("程序正常運(yùn)行")
...
發(fā)生了異常:錯(cuò)誤信息如下:
integer division or modulo by zero
第四種語法
使用 try ... except ... finally
如果代碼A發(fā)生了異常,則會(huì)走到代碼B的邏輯,最后不管有沒有發(fā)生異常都會(huì)走到代碼C
try: 代碼A except [exception] as e: 代碼B finally: 代碼C
舉個(gè)例子
發(fā)生異常的情況
>>> try:
... 1/0
... except ZeroDivisionError as e:
... print("發(fā)生了異常:錯(cuò)誤信息如下: \n" + str(e))
... finally:
... print("程序運(yùn)行結(jié)束!!")
...
發(fā)生了異常:錯(cuò)誤信息如下:
integer division or modulo by zero
程序運(yùn)行結(jié)束!!
不發(fā)生異常的情況
>>> try:
... 4/2
... except ZeroDivisionError as e:
... print("發(fā)生了異常:錯(cuò)誤信息如下: \n" + str(e))
... finally:
... print("程序運(yùn)行結(jié)束!!")
...
2
程序運(yùn)行結(jié)束!!
3. 捕獲多個(gè)異常?
每個(gè)except捕獲一個(gè)異常
一個(gè) try 語句可能有多個(gè) except 子句,以指定不同異常的處理程序,但是最多會(huì)執(zhí)行一個(gè)處理程序。
當(dāng)代碼 A 在運(yùn)行中拋出了異常時(shí),Python 解釋器會(huì)逐行運(yùn)行代碼,如果拋出的異常是 exception1
那么后面直接運(yùn)行代碼B,運(yùn)行完 B 后,就不會(huì)再判斷后面兩個(gè) except 語句了。
而如果不是 exception1
,而是 exception2
,那會(huì)運(yùn)行代碼C,而不會(huì)再運(yùn)行第三個(gè) except 語句了。
try:
代碼A
except [exception1] as e:
代碼B
except [exception2] as e:
代碼C
except [exception3] as e:
代碼D
舉個(gè)例子吧,下面這段代碼,由于 1/0
會(huì)拋出 ZeroDivisionError
錯(cuò)誤,所以前面兩個(gè)異常匹配都不成功,而在最后一個(gè) except 成功匹配上,最終打印出 除數(shù)不能為 0
try:
1/0
except IOError:
print("IO讀寫出錯(cuò)")
except FloatingPointError:
# 浮點(diǎn)計(jì)算錯(cuò)誤
print("計(jì)算錯(cuò)誤")
except ZeroDivisionError:
# 除數(shù)不能為 0
print("計(jì)算錯(cuò)誤")
# output: 計(jì)算錯(cuò)誤
一個(gè)except捕獲多個(gè)異常
上面的例子可以看出來,第二個(gè)異常和第三個(gè)異常是屬于同一類,就是 計(jì)算錯(cuò)誤
,異常處理的代碼是一樣的,那有沒有辦法將它們合并在一起呢,簡(jiǎn)化一下代碼呢?
答案是,可以的。
在 except 后面其實(shí)是可以接多個(gè)異常的,多個(gè)異常之間使用括號(hào)包裹。只要匹配上一個(gè)就算捕獲到,就會(huì)進(jìn)入相應(yīng)的代碼分支。
try:
1/0
except IOError:
print("IO讀寫出錯(cuò)")
except (ZeroDivisionError, FloatingPointError):
print("計(jì)算出錯(cuò)")
# output: 計(jì)算錯(cuò)誤
審核編輯:符乾江
-
python
+關(guān)注
關(guān)注
54文章
4756瀏覽量
84283 -
異常
+關(guān)注
關(guān)注
0文章
22瀏覽量
9213
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論