1.什麼是異常
error和exception的區別
- Error(錯誤)是系統中的錯誤,程序員是不能改變的和處理的,如系統崩潰,內存空間不足,方法調用棧溢等。遇到這樣的錯誤,建議讓程序終止。
- Exception(異常)表示程序可以處理的異常,可以捕獲且可能恢復。遇到這類異常,應該儘可能處理異常,使程序恢復運行,而不應該隨意終止異常。
常見的異常
AttributeError 、IOError 、ImportError 、IndexError、
SyntaxError、TypeError、ValueError、KeyError、NameError
• IndentationError: 縮進錯誤
• KeyboardInterrupt: Ctrl+C被按下
• UnboundLocalError : 有同名的全局變量
2.異常處理機制
2.1 異常處理的關鍵字
Python 的異常機制主要依賴 try 、except 、else、finally 和 raise五個關鍵字。
- try 關鍵字後縮進的代碼塊簡稱 try 塊,它裏面放置的是可能引發異常的代碼;
- except 關鍵字對應異常類型和處理該異常的代碼塊;
- 多個 except 塊之後可以放一個 else 塊,表明程序不出現異常時還要執行 else 塊;
- finally 塊用於回收在 try 塊裏打開的物理資源,異常機制會保證 finally 塊總被執行;
- raise 用於引發一個實際的異常,raise 可以單獨作爲語句使用,引發一個具體的異常對象;
下圖可以將它們的使用清晰明瞭得展示:
import os
dirname = 'dir'
filename = os.path.join(dirname, 'hello.html') # dir/hello.html
# try 關鍵字後縮進的代碼塊簡稱 try 塊,它裏面放置的是可能引發異常的代碼;
try:
with open(filename, 'w') as f:
f.write('hello')
# except 關鍵字對應異常類型和處理該異常的代碼塊;
except FileNotFoundError as e:
os.mkdir(dirname)
# 如何沒有產生任何異常時, 執行的內容
else:
print('no exception')
# finally 塊用於回收在 try 塊裏打開的物理資源,異常機制會保證 finally 塊總被執行
finally:
print("不管是否有異常都要執行的代碼")
這裏需要注意的一點是,如果try塊中有多個異常,一旦異常處理後,try塊不再執行。
try:
print(10/0) # ZeroDivisionError, 異常處理之後, try裏面的代碼並不會繼續執行。
print(a) # NameError
except ZeroDivisionError as e:
print('zeroError')
except NameError as e:
print('nameError')
else:
print('else')
finally:
print('always')
可以看到,try塊中本來應有兩個異常,但是處理完第一個異常後,try塊不再執行,直接執行finally塊。
2.2 異常處理的其他用途
除了處理實際的錯誤條件之外,對於異常還有許多其它的用處。在標準 Python 庫中一個普通的用法就是試着導入一個模塊,然後檢查是否它能使用。導入一個並不存在的模塊將引發一個 ImportError 異常。
你可以使用這種方法來定義多級別的功能――依靠在運行時哪個模塊是有效的,或支持多種平臺 (即平臺特定代碼被分離到不同的模塊中)。
3. 觸發異常
Python 允許程序自行引發異常,自行引發異常使用 raise 語句來完成。
raise [Exception [, args [, traceback]]]
raise語句中 Exception 是異常的類型(例如,NameError)參數標準異常中任一種,args 是自已提供的異常參數。
- 異常類層級關係
4. 自定義異常
==用戶自定義異常都應該繼承 Exception 基類或 Exception 的,在自定義異常類時基本不需要書寫更多的代碼,只要指定自定義異常類的父類即可。
class AgeError(ValueError):
pass
age = 1000
if 0 < age < 150:
print('age legal')
else:
raise AgeError('age error')
5. python異常使用規範
- 不要過度使用異常
- 不要使用過於龐大的 try 塊
- 不要忽略捕獲到的異常