python異常裝飾器--比較全的版本了


# 異常捕獲裝飾器(亦可用於類方法)
def try_except_log(f=None, max_retries: int = 5, delay: (int, float) = 1, step: (int, float) = 0,
                   exceptions: (BaseException, tuple, list) = BaseException, sleep=time.sleep,
                   process=None, validate=None, callback=None, default=None):
    """
    函數執行出現異常時自動重試的簡單裝飾器
    :param f: function 執行的函數。
    :param max_retries: int 最多重試次數。
    :param delay: int/float 每次重試的延遲,單位秒。
    :param step: int/float 每次重試后延遲遞增,單位秒。
    :param exceptions: BaseException/tuple/list 觸發重試的異常類型,單個異常直接傳入異常類型,多個異常以tuple或list傳入。
    :param sleep: 實現延遲的方法,默認為time.sleep。
    在一些異步框架,如tornado中,使用time.sleep會導致阻塞,可以傳入自定義的方法來實現延遲。
    自定義方法函數簽名應與time.sleep相同,接收一個參數,為延遲執行的時間。
    :param process: 處理函數,函數簽名應接收一個參數,每次出現異常時,會將異常對象傳入。
    可用於記錄異常日志,中斷重試等。
    如處理函數正常執行,並返回True,則表示告知重試裝飾器異常已經處理,重試裝飾器終止重試,並且不會拋出任何異常。
    如處理函數正常執行,沒有返回值或返回除True以外的結果,則繼續重試。
    如處理函數拋出異常,則終止重試,並將處理函數的異常拋出。
    :param validate: 驗證函數,用於驗證執行結果,並確認是否繼續重試。
    函數簽名應接收一個參數,每次被裝飾的函數完成且未拋出任何異常時,調用驗證函數,將執行的結果傳入。
    如驗證函數正常執行,且返回False,則繼續重試,即使被裝飾的函數完成且未拋出任何異常。
    如驗證函數正常執行,沒有返回值或返回除False以外的結果,則終止重試,並將函數執行結果返回。
    如驗證函數拋出異常,且異常屬於被重試裝飾器捕獲的類型,則繼續重試。
    如驗證函數拋出異常,且異常不屬於被重試裝飾器捕獲的類型,則將驗證函數的異常拋出。
    :param callback: 回調函數,函數簽名應接收一個參數,異常無法處理時,會將異常對象傳入。
    可用於記錄異常日志,發送異常日志等。
    :param default: 默認值/默認值生成函數
    :return: 被裝飾函數的執行結果。
    """

    # 帶參數的裝飾器
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # nonlocal delay, step, max_retries
            i = 0
            func_exc, exc_traceback = StopRetry, None
            while i < max_retries:
                try:
                    result = func(*args, **kwargs)
                    # 驗證函數返回False時,表示告知裝飾器驗證不通過,繼續重試
                    if callable(validate) and validate(result) is False:
                        continue
                    else:
                        return result
                except exceptions as ex:
                    func_exc, exc_traceback = ex, traceback.format_exc()
                    # 處理函數返回True時,表示告知裝飾器異常已經處理,終止重試
                    if callable(process):
                        try:
                            if process(ex) is True:
                                return default() if callable(default) else default
                        except Exception as e:
                            func_exc, exc_traceback = e, traceback.format_exc()
                            break
                finally:
                    i += 1
                    sleep(delay + step * i)
            else:
                # 回調函數,處理自動無法處理的異常
                if callable(callback):
                    callback(func_exc, exc_traceback)
                return default() if callable(default) else default
            pass

        return wrapper

    if callable(f):
        return decorator(f)
    return decorator

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM