Python從零開始學 Day06~異常處理
本文是上一篇文章的後續,詳情點擊該鏈接
在我們實際工作中,我們遇到的情況,並不會那麼完美。假如我們寫了個計算器,用戶偏偏輸入 2 / 0 這樣的式子,計算機底層是肯定報錯的。但是,這樣的報錯又不能讓客戶看見。怎麼辦呢?這個時候我們就需要異常處理機制來解決
比如說下述代碼,我們有了異常處理,就不會讓客戶看到異常
try:
a = int(input("請輸入式子"))
print(a)
except:
print('輸入錯誤!')
異常類的繼承層次
python中一切都是對象,異常也採用對象的方式來處理。處理過程:
拋出異常:在執行一個方法時,如果發生異常,則這個方法生成代表該異常的一個對象,停止當前執行路徑,並把異常對象提交給解釋器。
捕獲異常:解釋器得到該異常後,尋找相應的代碼來處理該異常。
try...一個 except 結構
try:
a = int(input("請輸入式子"))
print(a)
except BaseException:
print('輸入錯誤!')
try...多個 except 結構
try:
a = 5/0
print(a)
except ZeroDivisionError:
print("除數不能爲0");
except TypeError:
print("除數和被除數都應該爲數值類型")
except NameError:
print("變量不存在")
try...except...else 結構
try...except...else 結構增加了“else 塊”。如果 try 塊中沒有拋出異常,則執行 else 塊。如果 try 塊中拋出異常,則執行 except 塊,不執行 else 塊。
try:
a = 5/3
except ZeroDivisionError:
print("除數不能爲0");
except TypeError:
print("除數和被除數都應該爲數值類型")
except NameError:
print("變量不存在")
else:
print("a = " , a)
try…except…finally 結構
try...except...finally 結構中,finally 塊無論是否發生異常都會被執行;通常用來釋放 try 塊中 申請的資源。
try:
a = 5/0
except BaseException:
print('我是異常')
else:
print("a = " , a)
finally:
print("即使報了異常我也執行")
return 有兩種作用:結束方法運行、返回值。我們一般不把 return 放到異常處理結構 中,而是放到方法最後。
常見異常彙總
BaseException | 所有異常的基類 |
Exception | 常規錯誤的基類 |
ArithmeticError | 所有數值計算錯誤的基類 |
AssertionError | 斷言語句失敗 |
AttributeError | 對象沒有這個屬性 |
GeneratorExit | 生成器(generator)發生異常來通知退出 |
ImportError | 導入模塊/對象失敗 |
IndentationError | 縮進錯誤 |
IndexError | 序列中沒有此索引(index) |
KeyError | 映射中沒有這個鍵 |
OSError | 操作系統錯誤 |
OverflowError | 數值運算超出最大限制 |
OverflowWarning | 舊的關於自動提升爲長整型(long)的警告 |
StandardError | 所有的內建標準異常的基類 |
StopIteration | 迭代器沒有更多的值 |
SystemExit | 解釋器請求退出 |
TabError | Tab 和空格混用 |
TypeError | 對類型無效的操作 |
UnboundLocalError | 訪問未初始化的本地變量 |
UnicodeDecodeError | Unicode 解碼時的錯誤 |
EnvironmentError | 操作系統錯誤的基類 |
EOFError | 沒有內建輸入,到達 EOF 標記 |
UnicodeEncodeError | Unicode 編碼時錯誤 |
DeprecationWarning | 關於被棄用的特徵的警告 |
UnicodeError | Unicode 相關的錯誤 |
UnicodeTranslateError | Unicode 轉換時錯誤 |
UserWarning | 用戶代碼生成的警告 |
ValueError | 傳入無效的參數 |
Warning | 警告的基類 |
WindowsError | 系統調用失敗 |
ZeroDivisionError | 除(或取模)零 (所有數據類型) |
FloatingPointError | 浮點計算錯誤 |
SystemError | 一般的解釋器系統錯誤 |
FutureWarning | 關於構造將來語義會有改變的警告 |
LookupError | 無效數據查詢的基類 |
SyntaxWarning | 可疑的語法的警告 |
SyntaxError | Python 語法錯誤 |
RuntimeWarning | 可疑的運行時行爲(runtime behavior)的警告 |
RuntimeError | 一般的運行時錯誤 |
ReferenceError | 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象 |
PendingDeprecationWarning | 關於特性將會被廢棄的警告 |
NotImplementedError | 尚未實現的方法 |
KeyboardInterrupt | 用戶中斷執行(通常是輸入^C) |
NameError | 未聲明/初始化對象 (沒有屬性) |
MemoryError | 內存溢出錯誤(對於 Python 解釋器不是致命的) |
IOError | 輸入/輸出操作失敗 |
with 上下文管理
finally 塊由於是否發生異常都會執行,通常我們放釋放資源的代碼。其實,我們可以通 過 with 上下文管理,更方便的實現釋放資源的操作。
with 上下文管理可以自動管理資源,在 with 代碼塊執行完畢後自動還原進入該代碼之前的現場或上下文。不論何種原因跳出 with 塊,不論是否有異常,總能保證資源正常釋放。極大的簡化了工作,在文件操作、網絡通信相關的場合非常常用。
with open("d:/alvin.txt") as f:
for line in f:
print(line)
自定義異常
程序開發中,有時候我們也需要自己定義異常類。自定義異常類一般都是運行時異常,通常 繼承 Exception 或其子類即可。命名一般以 Error、Exception 爲後綴。
自定義異常由 raise 語句主動拋出
class AgeError(Exception): #繼承Exception
def __init__(self,errorInfo):
Exception.__init__(self)
self.errorInfo = errorInfo
def __str__(self):
return "年齡錯誤!"
if __name__ == "__main__":
age = 200
if age < 1 or age > 120:
raise AgeError(age) #這裏是raise不是return
else:
print("正常的年齡",age)