日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python编程中一些异常处理的小技巧

發布時間:2024/7/5 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python编程中一些异常处理的小技巧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

編程中經常會需要使用到異常處理的情況,在閱讀了一些資料后,整理了關于異常處理的一些小技巧記錄如下。

1 如何自定義異常

1.1 定義異常類

在實際編程中,有時會發現Python提供的內建異常的不夠用,我們需要在特殊業務場景下的異常。這時就需要我們來定義自己的異常。按照Python約定俗成的習慣,用戶定義的異常一般都是繼承于Exception類,由它開始拓展。后面我們可以看到這樣做在捕獲異常的時候會帶來很大的便利。

>>> class MyError(Exception):pass>>> raise MyError(u"something error") Traceback (most recent call last):File "<stdin>", line 1, in <module> __main__.MyError: something error

1.2 API異常相關的技巧

API的異常分為定義異常與調用API時如何捕獲異常兩個部分,這二者相輔相成。

1.2.1 定義API異常的技巧

在自己編寫API的時候,應該定義Root Exception——API中的根異常,其它異常都繼承于它。這樣的做法有兩個好處:

  • API代碼層次更清晰

  • API與調用程序代碼隔離

  • 假設存在如下場景:需要做一個鏈接數據庫服務的模塊。提供一個connect函數用于鏈接。那么,在鏈接的過程中,就會發生以下幾種情況:

    • socket連接超時

    • socket拒絕連接

    針對以上的情況,我們在模塊中定義幾個異常:

    # database.py class Error(Exception):"""Root exception for all exceptions raised by this module."""class SocketTimeError(Error):passclass SocketRefuseError(Error):passdef connect():pass

    1.2.2 調用API時異常捕獲的技巧

    這樣在調用API的時候就可以這樣使用:

    try:connect() except SocketTimeError as err:log.error(err) except SocketRefuseError as err:log.error(err) except Error as err:log.error("API Unexpected error:%s" % err) except Exception:log.error("API bug cause exception.")

    這樣精確定義多個異常,使得代碼層次清晰,增強了可讀性。值得注意的是:在代碼的最后還捕獲了Error以及Exception兩個異常,這兩個操作分別對應于可拓展性與健壯性的目的。

    捕獲Root Exception以提高可拓展性:

    我們知道,在實際鏈接數據庫時,還可能會出現用戶沒有登陸權限等問題。所以,我們需要在下一個版本中加入PermissionDeny這個異常。但是,舊的調用代碼已經寫好了,如果忘記修改的話,這個異常可能就會無法被處理,進而使得調用的程序奔潰。處于這樣的考慮,我們在調用API的時候,就應該再捕獲API的Root Exception,即使之后新加入了其它的異常,在這一個except中也能被捕獲而不影響調用程序。使得API模塊的可拓展性得到了提高。

    捕獲Exception以提高健壯性:

    在調用API的時候,難免可能出現API內部存在bug的情況。這個時候如果捕獲了Exception的話,就算API內部因為bug發生了異常,也不會影響到調用程序的正常運行。

    從這兩點中可以看出,要達到這種效果,其實都要依賴于常規異常繼承于Exception類這個規矩。這樣的架構劃分所帶來的好處是顯而易見的。

    2 與異常相關的編程藝術

    2.1 異常代替返回狀態碼

    我們經常需要編寫一些工具類的函數,往往在這些函數的處理流程中,會產生很多的狀態;而這些狀態也是調用者需要得到的信息。很多時候,會用一些具有意義的返回值來表示函數處理的狀態。

    比如:

    def write(content):if isinstance(content, basestring):f_handler = open("file.txt", 'w')try:f_handler.write(context)except Exception:return -2 # write file failelse:return 0 # write file succcessfinally:f_hanlder.close()else:return -1 # arg type error

    調用代碼:

    result = write() if result == -1:log.error(u"type error") elif result = -2:log.error(u"write error") else:log.info("ok")

    這種狀態碼的方式使用起來特別的不方便,調用者還需要去理解每個狀態碼的意義,帶來其它的學習成本;而且用if-else結構也不易于后期的程序拓展。所以,我們可以使用觸發異常來代替返回狀態碼,每個異常名其實就包含了狀態的意義在內(命名的藝術),使用起來也更好理解。

    使用異常的方式:

    class Error(Exception):passclass OpenFileError(Error):passclass WriteContentError(Error):pass def write(content):if isinstance(content, basestring):f_handler = open("file.txt", 'w')try:f_handler.write(context)except Exception:raise WriteContentErrorfinally:f_hanlder.close()else:raise OpenFileError

    調用代碼:

    try:write() except OpenFileError as e:log.error(e) except WriteContentError as e:log.error(e) except Error:log.error("API Error") except Exceptionlog.error("API Bug") else:log.info("ok")

    結合上面一點提到的使用API時的異常捕獲,使得調用代碼變得更佳靈活。

    2.3 異常處理與流程控制

    錯誤處理很重要,但如果它搞亂了代碼邏輯,就是錯誤的做法

    將異常處理與正常流程控制混為一談時,代碼是十分丑陋的。我們應該將二者分離,最好的做法就是將異常代碼塊抽離到另外的函數中。

    try:action_a()action_b()action_c() except ActionException as e:log.error(e) else:action_d()

    將異常處理分離:

    def action_executor():action_a()action_b()action_c()def action():try:action_executor()except ActionException as e:log.error(e)action() action_d()

    3 參考資料

    • Robert C·Martin的《Clean Code: A Handbook of Agile Software Craftsmanship》
    • Dusty Phillips的《Python 3 Object Oriented Programming》
    • Effective Python: 59 Specific Ways to Write Better Python · Effective Python
    • 8. Errors and Exceptions — Python 3.6.4 documentation
    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的Python编程中一些异常处理的小技巧的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。