1. 程式人生 > >python基礎教程(第三版)學習筆記(八)

python基礎教程(第三版)學習筆記(八)

第八章異常
異常事件可能是錯誤(如試圖除以零),也可能是通常不會發生的事情。為處理這些異常事件,可在每個可能發生這些事件的地方都使用異常處理機制。
8.1 異常是什麼
Python使用異常物件來表示異常狀態,並在遇到錯誤時引發異常。異常物件未被處理(或捕獲)時,程式將終止並顯示一條錯誤訊息(traceback)。
8.2讓事情沿著你指定的軌道出錯
8.2.1 raise語句
要引發異常,可使用raise語句,並將一個類(必須是Exception的子類)或例項作為引數。將類作為引數時,將自動建立一個例項。
'''

raise Exception("這裡發生了異常!")

'''

Traceback (most recent call last):
  File "xx.py", line 9, in <module>
    raise Exception("這裡發生了異常!")
Exception: 這裡發生了異常!


------------------
(program exited with code: 1)

請按任意鍵繼續. . .


在這示例(raise Exception)中,引發的是通用異常,並添加了錯誤訊息:這裡發生了異常!
在python中異常是一個類。其中Exception是通用異常類,其他幾乎所有異常都是從它派生而來。
除通用異常外常見的還有以下列出一些異常類:
i、   屬性異常 AttributeError       引用屬性或給它賦值失敗時引發
ii、  系統異常 OSError              作業系統不能執行指定的任務(如開啟檔案)時引發,有多個子類
iii、 索引異常 IndexError           使用序列中不存在的索引時引發,為LookupError的子類
iv、  鍵異常   KeyError            使用對映中不存在的鍵時引發,為LookupError的子類
v、   名稱異常 NameError           找不到名稱(變數)時引發
vi、  程式碼異常 SyntaxError         程式碼不正確時引發
vii、 型別異常 TypeError           將內建操作或函式用於型別不正確的物件時引發
vii、 值異常   ValueError          將內建操作或函式用於這樣的物件時引發:其型別正確但包含的值不合適
ix、  除法異常 ZeroDivisionError   在除法或求模運算的第二個引數為零時引發
8.2.2 自定義異常類
就像建立其他類一樣,但務必直接或間接地繼承Exception。也可在自定義異常類中新增方法。
'''

 

class My_Exception(Exception):
    def __init__(self):
        print("這是一個自定義異常,沒發生什麼。")


    

    
'''
8.3 捕獲異常
使用try/except語句在可能出現異常的地方捕獲異常。
'''
'''

try:
    x=int(input("請輸入一個數:"))
    y=int(input("請再輸入一個非零的數:"))
    print(x/y)
except ZeroDivisionError:
    print("對不起,你剛才誤把第二個數輸入零了!")


'''
    
'''

請輸入一個數:3
請再輸入一個非零的數:0
對不起,你剛才誤把第二個數輸入零了!


------------------
(program exited with code: 0)

請按任意鍵繼續. . .


8.3.1 不用提供引數
捕獲異常後,如果要重新引發它(即繼續向上傳播),可呼叫raise且不提供任何引數。
8.3.2 多個except子句
格式為
'''

try:
    pass
except Exception:
    pass
    pass
except My_Exception:
    pass
    pass


    
'''
8.3.3 一箭雙鵰
如果要使用一個except子句捕獲多種異常,可在一個元組中指定這些異常,如下所示:
'''

try:
    pass
except (A_Error,B_Error,C_Error):
    pass

'''
8.3.4 捕獲物件
要在except子句中訪問異常物件本身,可使用兩個而不是一個引數。(請注意,即便是在你捕獲多個異常時,也只向except提供了一個引數——一個元組。)
'''

try:
    x=int(input("請輸入一個數:"))
    y=int(input("請再輸入一個非零的數:"))
    print(x/y)
except ZeroDivisionError as e:
    print("對不起,你剛才誤把第二個數輸入零了!",e)

'''

請輸入一個數:1
請再輸入一個非零的數:0
對不起,你剛才誤把第二個數輸入零了! division by zero


------------------
(program exited with code: 0)

請按任意鍵繼續. . .


其中division by zero為引數e捕獲的ZeroDivisionError物件。
8.3.5 一網打盡
要使用一段程式碼捕獲所有的異常,只需在except語句中不指定任何異常類即可。形如:
'''

try:
    pass
except:
    print("這裡有異常。但不知道是什麼異常!!有點可怕。")

'''
像這樣捕獲所有的異常很危險,因為這不僅會隱藏你有心理準備的錯誤,還會隱藏你沒有考慮過的錯誤。
8.3.6 萬事大吉
在有些情況下,在沒有出現異常時執行一個程式碼塊很有用。為此,可像條件語句和迴圈一樣,給try/except語句新增一個else和finally子句。
(以下程式碼為湯老師授課筆記)
'''

try:
    #可能出現異常的程式碼
    pass
except Exception:
    #出現異常時執行的操作
    pass
else:
    #不出現異常時執行的操作
    pass
finally:
    #無論出現或不出現異常都要執行的程式碼
    pass

'''
8.3.7 最後
最後的finally子句,可用於在發生異常時執行清理工作。這個子句是與try子句配套的。

8.4 異常和函式
異常和函式有著天然的聯絡。如果不處理函式中引發的異常,它將向上傳播到呼叫函式的地方。如果在那裡也未得到處理,異常將繼續傳播,直至到達主程式(全域性作用域)。如果主程式中也沒有異常處理程式,程式將終止並顯示棧跟蹤訊息。

8.5 異常之禪
異常處理並不是很複雜。如果你知道程式碼可能引發某種異常,且不希望出現這種異常時程式終止並顯示棧跟蹤訊息,可新增必要的try/except或try/finally語句(或結合使用)來處理它。有些任務使用if/else完成時看似很自然,但實際上使用try/except來完成要好得多。
8.6 不那麼異常的情況
警告警告
,指出情況偏離了正軌,可使用模組warnings中的函式warn。
'''

from warnings import warn
warn("這裡好像出現點問題")

'''

xx.py:2: UserWarning: 這裡好像出現點問題
  warn("這裡好像出現點問題")


------------------
(program exited with code: 0)

請按任意鍵繼續. . .

(待續)