掉進懸崖的小白,學習python異常處理,做簡單總結(附自定義異常小例題)。

掉進懸崖的小白,學習python異常處理,做簡單總結

什麼是異常?

異常實際上是程序中錯誤導致中斷了正常的指令流的一種事件.

和傳統的方法比較異常的優點:

1.把錯誤代碼從常規代碼中分離出來
2.把錯誤傳播給調用堆棧
3. 按錯誤類型和錯誤差別分類
4. 系統提供了對於一些無法預測的錯誤的捕獲和處理

什麼情況下使用異常機制?

1.當方法因爲自身無法控制的原因而不能完成其任務
文件不存在,網絡連接無法建立……
2.處理在引入模塊中拋出的異常
3.在大的項目中採用統一的方式處理異常時
如編寫一個文字處理器
4.異常應該是不經常發生但卻可能發生的故障
一定發生的事件不應該用異常機制來處理
5.異常處理用於使系統從故障中恢復
提示信息/不產生無效的結果/釋放資源

注意事項:
1.不同的異常處理策略
關鍵性應用(處理所有異常)
實驗軟件(可以忽略許多異常)
2.終止程序會導致資源泄漏,利用異常處理釋放資源
3.儘可能近地處理異常,這樣程序清晰易讀
4.能在局部處理的錯誤不要使用異常機制
異常機制的處理比正常處理效率低

處理機制

捕獲並處理異常
try:
# 接受監視的程序塊,在此區域內發生的異常,由except中指定的程序處理
#不能有其它語句分隔
except 要處理的異常種類1 as 標識符1:
# 處理異常
except 要處理的異常種類2 as 標識符2:
# 處理異常

或者
except (異常種類1, 異常種類2…) as 標識符…:
# 處理異常
或者
except:
# 上面未捕獲的處理異常
else:
# 未監視到異常時執行的代碼
finally:
# 有無異常均會執行的代碼

try語句:異常監視塊

作用:監視該代碼塊是否有異常發生,若有異常,產生異常對象並拋出

except語句:異常處理代碼塊

作用:捕捉try語句中拋出的異常,並按照代碼塊中的語句處理

格式:標識符主要用於解析異常對象
except 要處理的異常種類 as 標識符:
except (異常種類1, 異常種類2…) as 標識符…:

注意:

1.每個try語句必須伴隨1-n個except語句
2.異常總是由距離產生異常最近的匹配except代碼段處理
3.try-except可以嵌套使用
4.匹配的except執行完畢後,同級的except將被忽略
5.先except小的再except老的
6.整個執行流程中若無except處理 程序中斷!
7.except的類型應儘量精確
8.請注意你調用的方法是否有可能拋出異常
9.except中也可能產生異常 會拋給嵌套的上一級處理
10.永遠不要except中吞掉異常,否則在系統發生異常時,你永遠不知道到底發生了什麼:
推薦:
except BaseException:
# 處理異常的語句
raise #再次將異常拋出
11.try-except機制不該被用於流程控制,異常情形應該是很稀少的,而不是經常性的

else

等同於for…else和while…else
在不發生異常時執行的語句塊

一定會執行的程序塊—finally

異常處理的統一出口
finally:
# 不論發生什麼異常(或者不發生任何異常),都要執行的部分;
finally:
1.捕獲異常的最後一步是通過finally語句爲異常處理提供一個統一的出口,使得在控制流程轉到程序的其他部分以前,能夠對程序的狀態作統一的管理。
2.無論try所指定的程序塊中是否拋出異常,也無論except語句的異常類型是否與所拋棄的異常的類型一致,finally所指定的代碼都要被執行,它提供了統一的出口。
3.通常在finally語句中可以進行資源的清除工作,如關閉打開的文件、刪除臨時文件等。

finally和return的關係:
1.當try和except中有return時,finally仍然會執行;
2.finally是在return後面的表達式運算後執行的(此時並沒有返回運算後的值,而是先把要返回的值保存起來,不管finally中的代碼如何修改,返回的值都不會改變,仍然是之前保存的值),所以函數返回值是在finally執行前確定的;

異常分類

  • BaseException # 所有異常的父類
    • SystemExit # 由sys.exit()拋出的異常
    • KeyBoardInterrupt # 通常由ctrl+c或者Delete拋出的異常
    • GeneratorExit # 生成器(generator)發生異常來通知退出
    • Exception # 常規異常基類
      • StopIteration # 迭代器沒有更多的值
      • StopAsyncIteration # 由異步迭代的__anext__()拋出的異常
      • ArithmeticError # 各種算數錯誤引起的異常
        • FloatingPointError # 浮點數操作錯誤
        • OverflowError # 結果超出範圍
        • ZeroDivisionError # 0爲除數異常
    • AssertionError # assert錯誤異常
    • AttributeError # 屬性引用異常
    • BufferError # 緩存錯誤
    • EOFError # 讀不到數據
    • ImportError # import錯誤
      • ModuleNotFoundError # 找不到模塊
    • LookupError # 由索引和key值引起的異常
      • IndexError # 索引錯誤
      • KeyError # 字典key值錯誤
    • MemortError # 內存溢出異常
    • NameError # 本地和全局找不到變量名
      • UnboundLocalError # 局部變量沒有賦值
    • OSError # system錯誤
      • BlockingIOError # 調用阻塞異常錯誤
      • ChildProcessError # 子進程
      • ConnectionError # 連接
        • BrokenPipeError # 管道讀寫異常
        • ConnectionAbortedError # 連接失敗
        • ConnectionRefusedError # 連接拒絕
        • ConnectionResetError # 連接重置
      • FileExistsError # 創建文件和文件夾錯誤
      • FileNotFoundError # 文件未找到
      • InterruptedError # 中斷錯誤
      • IsADirectoryError # 文件操作用在文件夾上
      • NotADirectoryError # 不是文件夾
      • PermissionError # 權限
      • ProcessLookupError # 進程不存在
      • TimeoutError # 超時
    • ReferenceError # 試圖訪問已經垃圾回收的對象異常
    • RuntimeError #
      • NotImplementedError # 未實現抽象方法異常
      • RecursionError # 超出最大遞歸深度
    • SyntaxError # 語法錯誤
      • IndentationError # 縮進錯誤
        • TabError # Tab 和空格混用
    • SystemError # 解釋器中斷
    • TypeError # 對類型無效的操作
    • ValueError # 賦值錯誤
      • UnicodeError # Unicode 相關的錯誤
        • UnicodeEncodeError # unicode編碼錯誤
        • UnicodeDecodeError # unicode解碼錯誤
        • UnicodeTranslateError # unicode轉換錯誤
    • Warning # 警告的基類
      • DeprecationWarning # 關於被棄用的特徵的警告
      • PendingDeprecationWarning # 表明此操作將來會被棄用
      • UserWarning # 用戶代碼生成的警告
      • SyntaxWarning # 可疑的語法的警告
      • RuntimeWarning # 可疑的運行時行爲警告
      • FutureWarning # 關於構造將來語義會有改變的警告
      • ImportWarning # 導入警告
      • UnicodeWarning # unicode相關警告
      • BytesWarning # 字節相關警告
      • ResourceWarning # 資源使用情況警告

手動拋出異常

手動拋出異常的方法:raise 空|異常對象
注意:
單raise時,會將當前捕獲的異常直接再次拋出

raise exception_obj;
拋出異常: 不是出錯產生,而是人爲地拋出

1.任何從BaseException派生的類都可以用raise語句拋出,拋出異常用來表明程序遇到的錯誤無法正常執行而需要異常處理
raise BaseException(“some infomation”);
2.異常拋出點後的代碼在拋出異常後不再執行
也可以說異常的拋出終止了代碼段的執行

自定義異常

異常是一個類,用戶定義的異常一般繼承自Exception:
‘’‘自定義的異常類’’’
來個例題:

# 在定義銀行類時,若取錢數大於餘額則作爲異常處理
# (InsufficientFundsException).
# 思路:產生異常的條件是餘額少於取額,  因此是否拋出異常
# 要判斷條件
# 取錢是Withdrawal 方法中定義的動作,因此在該方法中產生
# 異常.
# 處理異常安排在調用Withdrawal 的時候,因此Withdrawal
# 方法要聲明異常,由上級方法調用
# 要定義好自己的異常類
# 要求:捕捉到的異常對象內有餘額和取額的信息

class GetmoneyError(Exception):

    def __init__(self, acc, get_money) -> None:
        super().__init__()
        self.acc = acc
        self.get_money = get_money

    def __str__(self) -> str:
        return f"異常發生的賬戶是{self.acc.acc_id}," \
            f"情況爲取款金額{self.get_money},超出賬戶餘額{self.acc.money}"


class Account:

    def __init__(self, acc_id, money) -> None:
        super().__init__()
        self.acc_id = acc_id
        self.money = money

    def withdraw(self, get_money):
        if 0 < get_money < self.money:
            return get_money
        else:
            # print("餘額不足")
            # pass
            raise GetmoneyError(self, get_money)


if __name__ == '__main__':
    try:
        acc = Account("001", 123)
        acc.withdraw(244)
    except GetmoneyError as e:
        print(e)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章