簡介
異常指程序運行過程中出現的非正常現象,例如用戶輸入錯誤、除數爲零、需 要處理的文件不存在、
數組下標越界等。 所謂異常處理,就是指程序在出現問題時依然可以正確的執行剩餘的程序,而 不會
因爲異常而終止程序執行。
python 中,引進了很多用來描述和處理異常的類,稱爲異常類。異常類定義中 包含了該類異常的信
息和對異常進行處理的方法。
下面較爲完整的展示了 python 中內建異常類的繼承層次:
python 中一切都是對象,異常也採用對象的方式來處理。處理過程:
1. 拋出異常:
在執行一個方法時,如果發生異常,則這個方法生成代表該 異常的一個對象,停止當前執行路徑,
並把異常對象提交給解釋器。
2. 捕獲異常:
解釋器得到該異常後,尋找相應的代碼來處理該異常。
一、try…一個 except 結構
try…except 是最常見的異常處理結構。結構如下:
try:
被監控的可能引發異常的語句塊
except BaseException [as e]:
異常處理語句塊
try 塊包含着可能引發異常的代碼,except 塊則用來捕捉和處理髮生的異常。執行的時 候,如果try塊
中沒有引發異常,則跳過 ecept 塊繼續執行後續代碼;
執行的時候,如果 try塊中發生了異常,則跳過 try 塊中的後續代碼,跳到相應的except塊中處理異常;
異常處理完後,繼續執行後續代碼。
二、try…多個 except 結構
上面的結構可以捕獲所有的異常,工作中也很常見。但是,從經典理論考慮,一般建議儘量捕獲
可能出現的多個異常(按照先子類後父類的順序),並且針對性的寫出異常處理代 碼。爲了避免遺
漏可能出現的異常,可以在最後增加 BaseException。結構如下:
try:
被監控的、可能引發異常的語句塊
except Exception1:
處理 Exception1 的語句塊
except Exception2:
處理 Exception2 的語句塊
...
...
...
except BaseException:
處理可能遺漏的異常的語句塊
三、try…except…else 結構
try...except...else結構增加了“else 塊”。如果try塊中沒有拋出異常,則執行 else 塊。如果try塊中
拋出異常,則執行except塊,不執行else塊。
四、try…except…finally 結構
try...except...finally 結構中,finally塊無論是否發生異常都會被執行;通常用來釋放 try 塊中申請
的資源。
五、return 語句和異常處理問題
由於return有兩種作用:結束方法運行、返回值。我們一般不把return放到異常處理結構中,而是
放到方法最後。
示例代碼:
def test01():
print("step1")
try:
x = 3/0
# return "a"
except:
print("step2")
print("異常:0 不能做除數")
# return "b"
finally:
print("step3")
# return "c"
print("step4")
# 一般不要將return語句放到try、except、else、 finally塊中,
# 會發生一些意想不到的錯誤。建議放到方法最後。
return "d"
print(test01())
=====================運行結果=============================
step1
step2
異常:0 不能做除數
step3
step4
e
=====================運行結果=============================
六、常見異常彙總
七、with 上下文管理
finally塊由於是否發生異常都會執行,通常我們放釋放資源的代碼。其實,我們可以通過with上下文
管理,更方便的實現釋放資源的操作。
with 上下文管理的語法結構如下:
with context_expr [ as var]:
語句塊
with 上下文管理可以自動管理資源,在with代碼塊執行完畢後自動還原進入該代碼之前的現場
或上下文。不論何種原因跳出with塊,不論是否有異常,總能保證資源正常釋放。極大的簡化了工
作,在文件操作、網絡通信相關的場合非常常用。
八、trackback 模塊
使用 Traceback 模塊打印異常信息,示例代碼:
import traceback
file_path = "E:\PythonProject\File_Test\學習文件\\file01.txt"
try:
a = 1 / 0
except:
traceback.print_exc() # 打印異常信息
with open(r"{0}".format(file_path), "a") as f:
traceback.print_exc(file=f) # 使用 traceback 將異常信息寫入日誌文件
print('寫入信息!!!')
=====================運行結果=============================
Traceback (most recent call last):
File "E:/PythonProject/CSDNPythonLearn/exception/exception_test02.py", line 5, in <module>
a = 1 / 0
ZeroDivisionError: division by zero
=====================運行結果=============================
九、自定義異常類
程序開發中,有時候我們也需要自己定義異常類。自定義異常類一般都是運行時異常,通常
繼承Exception或其子類即可。命名一般以Error、Exception爲後綴
示例代碼:
class ScoreError(Exception):
def __init__(self, error_info):
Exception.__init__(self)
self.error_info = error_info
def __str__(self):
return str(self.error_info) + '錄入分數錯誤,應在0-101之間!!!'
if __name__ == "__main__":
score = int(input("請輸入一個分數:"))
if score < 0 or score > 100:
raise ScoreError(score)
else:
print("分數輸入正確,請確認:{0}".format(score))
=====================運行結果=============================
請輸入一個分數:777
Traceback (most recent call last):
File "E:/PythonProject/CSDNPythonLearn/exception/exception_test03.py", line 14, in <module>
raise ScoreError(score)
__main__.ScoreError: 777錄入分數錯誤,應在0-101之間!!!
=====================運行結果=============================
學習來自:北京尚學堂高琪老師 Python 400集