目錄
Python内置異常類的層次結構
Python異常處理
try 語句
try-except 語句
try-finally 語句
raise 語句
else 語句
with 語句
Python内置異常類的層次結構
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
AssertionError
斷言語句(assert)失敗。assert 語句後條件為假時,程式自動崩潰并抛出 AssertionError 的異常。
一般用它在程式中置入檢查點,當需要確定程式中的某個條件一定為真才能讓程式正常工作時,assert 關鍵字就非常有用。
>>> assert 3 < 4
>>> assert 4 < 3
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
assert 4 < 3
AssertionError
>>> my_list = ['ABC']
>>> assert len(my_list) > 0
>>> my_list.pop()
'ABC'
>>> assert len(my_list) > 0
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
assert len(my_list) > 0
AssertionError
AttributeError
嘗試通路未知的對象屬性。當試圖通路的對象屬性不存在時抛出的異常。
>>> my_list = []
>>> my_list.huhan
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
my_list.huhan
AttributeError: 'list' object has no attribute 'huhan'
EOFError
使用者輸入檔案末尾标志EOF(Ctrl+d)
FloatingPointError
浮點計算錯誤
GeneratorExit
generator.close()方法被調用的時候
ImportError
導入子產品失敗的時候
IndentationError
縮進錯誤
IndexError
索引超出序列的範圍
>>> my_list = [1, 2, 3]
>>> my_list[3]
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
my_list[3]
IndexError: list index out of range
KeyError
字典中查找一個不存在的關鍵字
>>> my_dict = {'one': 'いち', 'two': 'に', 'three': 'さん'}
>>> my_dict['one']
'いち'
>>> my_dict['four']
Traceback (most recent call last):
File "<pyshell#33>", line 1, in <module>
my_dict['four']
KeyError: 'four'
KeyboardInterrupt
使用者輸入中斷鍵(Ctrl+c)
MemoryError
記憶體溢出(可通過删除對象釋放記憶體)
NameError
嘗試通路一個不存在的變量
>>> abc
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
abc
NameError: name 'abc' is not defined
NotImplementedError
尚未實作的方法
OSError
作業系統産生的異常(例如打開一個不存在的檔案)
>>> my_file = open('D:\\Python\\test\\no.txt', 'r')
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
my_file = open('D:\\Python\\test\\no.txt', 'r')
FileNotFoundError: [Errno 2] No such file or directory: 'D:\\Python\\test\\no.txt'
OverflowError
數值運算超出最大限制
ReferenceError
弱引用(weak reference)試圖通路一個已經被垃圾回收機制回收了的對象
RuntimeError
一般的運作時錯誤
StopIteration
疊代器沒有更多的值
SyntaxError
Python的文法錯誤
>>> print('a')
a
>>> print 'a'
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('a')?
TabError
Tab和空格混合使用
SystemError
Python編譯器系統錯誤
SystemExit
Python編譯器程序被關閉
TypeError
不同類型間的無效操作
>>> age = 12
>>> print("I'm " + str(age) +" years old.")
I'm 12 years old.
>>>
>>> print("I'm " + age +" years old.")
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
print("I'm " + age +" years old.")
TypeError: can only concatenate str (not "int") to str
UnboundLocalError
通路一個未初始化的本地變量(NameError的子類)
UnicodeError
Unicode相關的錯誤(ValueError的子類)
UnicodeEncodeError
Unicode編碼時的錯誤(UnicodeError的子類)
UnicodeDecodeError
Unicode解碼時的錯誤(UnicodeError的子類)
UnicodeTranslateError
Unicode轉換時的錯誤(UnicodeError的子類)
ValueError
傳入無效的參數
ZeroDivisionError
除數為零
>>> 5 / 0
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
5 / 0
ZeroDivisionError: division by zero
Python異常處理
try 語句
try-except 語句
語句格式:
try:
檢測範圍
except Exception[as reason]:
出現異常(Exception)後的處理代碼
try 語句檢測範圍内一旦出現異常,剩下的語句将不會被執行。
例:
f = open('不一定存在的檔案.txt')
print(f.read())
f.close()
# 檔案不存在時報錯:
'''
FileNotFoundError: [Errno 2] No such file or directory: '不一定存在的檔案.txt'
'''
# 不帶參數,知其然不知其是以然~~
try:
f = open('不一定存在的檔案.txt')
print(f.read())
f.close()
except OSError: # FileNotFoundError 屬 OSError
print('檔案或路徑不存在呀不存在~~~')
'''
檔案或路徑不存在呀不存在~~~
'''
# 帶參數,列出錯誤原因。知其然亦知其是以然~~
try:
f = open('不一定存在的檔案.txt')
print(f.read())
f.close()
except OSError as reasonXYZ123_custom: # 可以自定義
print('檔案或路徑不存在呀不存在~~~\n錯誤的原因是:' + str(reasonXYZ123_custom)) # 需将錯誤内容強制變為字元串
'''
檔案或路徑不存在呀不存在~~~
錯誤的原因是:[Errno 2] No such file or directory: '不一定存在的檔案.txt'
'''
一個try語句還可以搭配多個except語句,對關注的異常進行處理。
try:
sum = 1 + '1' # 發現異常将跳過其他語句
f = open('不一定存在的檔案.txt')
print(f.read())
f.close()
except OSError as reasonXYZ123:
print('檔案或路徑不存在呀不存在~~~\n錯誤的原因是:' + str(reasonXYZ123))
except TypeError as reasonXYZ123: #這個錯誤先發生~
print('類型出錯啦~~~\n錯誤的原因是:' + str(reasonXYZ123))
'''
類型出錯啦~~~
錯誤的原因是:unsupported operand type(s) for +: 'int' and 'str'
'''
對異常進行統一處理:
except後邊還可以跟多個異常,然後對這些異常進行統一的處理:
try:
sum = 1 + '1' # 錯上加錯~
f = open('不一定存在的檔案.txt')
print(f.read())
f.close()
except (TypeError, OSError) as reasonXYZ123: # except後邊跟多個異常
print('出錯啦~~~\n錯誤的原因是:' + str(reasonXYZ123))
'''
出錯啦~~~
錯誤的原因是:unsupported operand type(s) for +: 'int' and 'str'
'''
try:
sum = 1 + '1'
f = open('不一定存在的檔案.txt')
print(f.read())
f.close()
except (TypeError, OSError): # 不報Error原因
print('出錯啦~~~')
'''
出錯啦~~~
'''
捕獲所有異常:
缺點:會隐藏所有未想到并且未做好處理準備的錯誤。如:Ctrl+C 試圖終止程式,卻被解釋為 KeyboardInterrupt 異常。
try:
int('abc') # 錯1
sum = 1 + '1' # 錯2
f = open('不一定存在的檔案.txt') # 錯3
print(f.read())
f.close()
except:
print('出錯啦!!!')
'''
出錯啦!!!
'''
try-finally 語句
定義清理行為。如果一個異常在 try 子句裡(或者在 except 和 else 子句裡)被抛出,而又沒有任何的 except 把它截住,那麼這個異常會在 finally 子句執行後再次被抛出。
finally 語句塊無論如何都将被執行:
try 語句塊沒有錯誤:跳過 except 語句塊執行 finally 語句塊的内容。
try 語句塊出現錯誤:先執行 except 語句塊再執行 finally 語句塊的内容。
try:
檢測範圍
except Exception[as reason]:
出現異常(Exception)後的處理代碼
finally:
無論如何都會被執行的代碼
例:
try:
f = open('D:\\Python\\test\\存在的檔案.txt', 'w') # 成功打開
print(f.write('寫入檔案的東西')) # 寫入字元串,傳回字元長度
sum = 1 + '1' # Error
f.close() # 因為Error,跳過關閉操作,資料在緩存,寫入未儲存至檔案
except (TypeError, OSError):
print('出錯啦~~~')
'''
7
出錯啦~~~
'''
解決上例未儲存的問題:
try:
f = open('D:\\Python\\test\\存在的檔案.txt', 'w')
print(f.write('寫入檔案的東西'))
sum = 1 + '1' # Error
except (TypeError, OSError):
print('出錯啦~~~')
finally:
f.close() # 無論如何都将被執行
'''
7
出錯啦~~~
'''
raise 語句
使用 raise 語句抛出一個指定的異常。
>>> raise # 單獨使用
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
raise
RuntimeError: No active exception to reraise
>>>
>>> raise ZeroDivisionError # 抛出指定異常
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
raise ZeroDivisionError
ZeroDivisionError
>>>
>>> raise ZeroDivisionError('除數不能為零~~!') # 加參數,對異常進行解釋
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
raise ZeroDivisionError('除數不能為零~~!')
ZeroDivisionError: 除數不能為零~~!
else 語句
見:《Python:else語句》
with 語句
with 語句可以保證諸如檔案之類的對象在使用完之後一定會正确的執行它的清理方法。
with open("myfile.txt") as f:
for line in f:
print(line, end="")
以上這段代碼執行完畢後,就算在處理過程中出問題了,檔案 f 總是會關閉。
例:
try:
f = open('data.txt', 'w')
for each_line in f:
print(each_line)
except OSError as reason:
print('出錯啦!' + str(reason))
finally:
f.close()
使用 with 語句改寫:
try:
with open('data.txt', 'w') as f: # with關注檔案,在沒用的時候自動調用f.close()
for each_line in f: # 注意縮進
print(each_line)
except OSError as reason:
print('出錯啦!' + str(reason))