簡介
本文主要介紹python的異常處理機制,包括:
- 如何使用異常處理
- 異常的傳遞
- 拋出異常
由於比較簡單,因此這裏介紹的不是很詳細。
有一些代碼來源於網絡。
如何使用異常處理
所有的面嚮對象語言對異常的處理方式大同小異,在python中的處理異常的結構如下:
try:
# 可能出錯的程序
except (Exception1, Exception2): # 注意,python3中如果同時處理多個異常,需要將多個異常放在元組中。
# 捕獲到異常後對應的處理方法
except Exception as e:
# 捕獲到異常後對應的處理方法
print(e)
raise
else:
# 如果沒有捕獲到異常對應處理方法
finally:
# 觸發異常或者不觸發異常都需要處理的部分
接下來我們對上述結構逐一介紹。
try … except
try
裏面放可能出現問題的代碼
except
裏面放捕獲到錯誤之後的處理的方法
try:
print(num)
except NameError as e:
print('捕獲到的錯誤信息:',e)
# Output:
捕獲到的錯誤信息: name 'num' is not defined
except 捕獲多個異常
直接在except將多個異常的名字放在元組裏即可:
try:
open('hahaha')
except (NameError, IOError):
print('catch exception')
# Output
catch exception
捕獲所有異常
Exception
類是所有異常類的父類,可以直接用Exception
接收所有異常。
try:
print(num)
except Exception as e:
print(e)
# Output:
name 'num' is not defined
else
當沒有異常使,可以用else
處理。
try:
num = 100
print(num)
except Exception as e:
print(e)
else:
print('not catch IOError!')
# Output
100
not catch IOError!
try … finally
無論檢測到還是檢測不到異常,有些代碼都需要執行,此時放在finally
裏。
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
except:
#如果在讀取文件的過程中,產生了異常,那麼就會捕獲到
#比如 按下了 ctrl+c
pass
finally:
f.close()
print('關閉文件')
except:
print("沒有這個文件")
異常的傳遞
使用try ... except
捕獲異常還有一個好處,即異常可以跨越多層進行傳遞。如下面的例子:
def test1():
print("----test1-1----")
print(num)
print("----test1-2----")
def test3():
try:
print("----test3-1----")
test1()
print("----test3-2----")
except Exception as result:
print("捕獲到了異常,信息是:%s"%result)
print("----test3-3----")
test3()
#Output
----test3-1----
----test1-1----
捕獲到了異常,信息是:global name 'num' is not defined
----test3-3----
這樣我們就可以不必在每個可能出現錯誤的地方都寫上try
,而只需要在合適的層次進行處理即可。
拋出異常
拋出已有異常
可以通過raise
來將捕獲到的異常再拋出去。如下:
class Test(object):
def __init__(self, switch):
self.switch = switch #開關
def calc(self, a, b):
try:
return a/b
except Exception as result:
if self.switch:
print("捕獲開啓,已經捕獲到了異常,信息如下:")
print(result)
else:
#重新拋出這個異常,此時就不會被這個異常處理給捕獲到,從而觸發默認的異常處理
raise
a = Test(True)
a.calc(11,0)
print("----------------------華麗的分割線----------------")
a.switch = False
a.calc(11,0)
#Output
捕獲開啓,已經捕獲到了異常,信息如下:
integer division or modulo by zero
----------------------華麗的分割線----------------
Traceback (most recent call last):
File "test.py", line 23, in <module>
a.calc(11,0)
File "test.py", line 7, in calc
return a/b
ZeroDivisionError: integer division or modulo by zero
拋出自定義異常
自定義異常需要繼承Exception
類即可,如下:
# -*- coding:utf8 -*-
class NumError(Exception):
def __init__(self, num, max_):
self.num = num
self.max_ = max_
try:
num = 101
if num > 100:
raise NumError(num, 100)
except NumError as e:
print('%d is too large, max is %d' %(e.num, e.max_))
# Output
101 is too large, max is 100