天天看點

Python異常及處理Python内置異常類的層次結構Python異常處理

目錄

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))