python 模块 tenacity 和 retrying 重试库

一、介绍

tenacity 和 retrying 都是 Python 中常用的重试库,用于实现在出现异常或特定条件下进行自动重试的功能。它们具有类似的目标,但在实现和使用上有一些区别。

  1. retrying:
  • retrying 是一个简单而强大的重试库,提供了 @retry 装饰器来修饰函数或方法,实现自动重试的功能。
  • retrying 的参数可以灵活配置,可以控制重试的次数、延迟时间、重试条件等。
  • retrying 支持多种等待策略,如固定间隔、随机间隔和指数退避等待策略。
  • retrying 的官方网站是 https://github.com/rholder/retrying
  1. tenacity:
  • tenacity 是一个强大且灵活的重试库,提供了多种重试策略和功能。
  • tenacity 的主要特点是可以通过自定义的 stop、wait 和 retry 策略来灵活控制重试的行为。
  • tenacity 支持多种重试条件,可以基于异常类型、返回值、时间等进行重试。
  • tenacity 还提供了一些高级功能,如超时、异步重试、断言等。
  • tenacity 的官方网站是 https://github.com/jd/tenacity
二、安装
pip install tenacity
pip install retrying
三、retrying下的retry
  1. @retrying.retry(stop_max_attempt_number,stop_max_delay,wait_fixed,wait_random_min,wait_random_max,wait_exponential_multiplier,wait_exponential_max,retry_on_exception,wrap_exception,retry_on_result):装饰器,用于修饰函数或方法,实现自动重试
  • stop_max_attempt_number:指定重试的最大次数。当达到最大重试次数后,停止重试。默认值为 5。
  • stop_max_delay:指定重试的最大总延迟时间(毫秒)。当重试的总延迟时间超过该值时,停止重试。默认值为 None,表示没有最大延迟时间限制。
  • wait_fixed:指定重试的固定间隔时间(毫秒)。在每次重试之间等待固定的时间间隔。默认值为 None,表示没有固定间隔时间,而是使用其他的等待策略。
  • wait_random_min 和 wait_random_max:指定重试的随机间隔时间范围(毫秒)。在每次重试之间等待一个随机的时间间隔,范围为 [wait_random_min, * * wait_random_max]。默认值为 None,表示没有随机间隔时间,而是使用其他的等待策略。
  • wait_exponential_multiplier 和 wait_exponential_max:指定指数退避等待策略的参数。wait_exponential_multiplier 表示每次重试的等待时间将乘以的倍数,wait_exponential_max 表示重试的等待时间的最大值。默认值为 None,表示不使用指数退避等待策略。
  • retry_on_exception:指定在哪些异常发生时进行重试。可以是一个异常类型或异常类型的元组。默认值为 True,表示在任何异常发生时都进行重试。
  • wrap_exception:指定是否将重试期间捕获的异常包装在一个特定的异常类型中。默认值为 False,表示不进行异常包装。
  • retry_on_result:指定在哪些返回值情况下进行重试。可以是一个函数,当函数返回 True 时触发重试。默认值为 False,表示不根据返回值情况进行重试。
四、tenacity中的retry
  1. @tenacity.retry(stop,wait,retry,reraise,before,after,before_sleep,retry_error_callback,sleep):装饰器,用于修饰函数或方法,实现自动重试
  • stop:停止策略,用于定义何时停止重试的条件,停止策略函数,tenacity.stop或者自定义函数。
  • wait:等待策略,用于定义重试之间的等待时间,等待策略函数,tenacity.wait或者自定义函数。
  • retry:重试条件,用于定义触发重试的条件,tenacity.retry或者自定义函数。
  • reraise:布尔值,表示是否重新引发最后一次异常。
  • before:在每次重试之前执行的操作,指定一个函数t,enacity.before。
  • after:在每次重试之后执行的操作,指定一个函数,tenacity.after。
  • before_sleep:在等待之前执行的操作,指定一个函数,tenacity.before_sleep或者自定义函数。
  • retry_error_callback:重试错误回调函数,用于处理重试过程中的错误,指定一个函数。
  • sleep:在重试之前进行睡眠的函数,指定一个函数。
五、停止策略:tenacity.stop
  1. 自定义函数
    import tenacity
    
    
    def stop(retry_state):
        print(retry_state)
        return True
    
    def retry_if_result_none(retry_state):
        print(retry_state)
        return True
    
    @tenacity.retry(retry=retry_if_result_none,stop=stop)
    def my_function():
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  2. tenacity.stop.stop_after_attempt:停止策略,当重试次数达到指定次数时停止重试。
    import tenacity
    
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,stop=tenacity.stop.stop_after_attempt(3))
    def my_function():
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  3. tenacity.stop.stop_after_delay:停止策略,当重试持续时间达到指定时间时停止重试。
    import tenacity
    
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,stop=tenacity.stop.stop_after_delay(2))
    def my_function():
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  4. tenacity.stop.stop_all:停止策略,要求所有停止条件都满足才停止重试。
    import tenacity
    import time
    
    stop_policy = tenacity.stop.stop_all(
        tenacity.stop.stop_after_attempt(10),
        tenacity.stop.stop_after_delay(2)
    )
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,stop=stop_policy)
    def my_function():
        time.sleep(1)
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  5. tenacity.stop.stop_any:停止策略,只要有任何一个停止条件满足就停止重试。
    import tenacity
    import time
    
    stop_policy = tenacity.stop.stop_any(
        tenacity.stop.stop_after_attempt(10),
        tenacity.stop.stop_after_delay(2)
    )
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,stop=stop_policy)
    def my_function():
        time.sleep(1)
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  6. tenacity.stop.stop_never:停止策略,永不停止重试。
    import tenacity
    import time
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,stop = tenacity.stop.stop_never)
    def my_function():
        time.sleep(1)
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  7. tenacity.stop.stop_when_event_set:停止策略,当指定事件被设置时停止重试。
    import tenacity
    import threading
    
    stop_event = threading.Event()
    
    stop_policy = tenacity.stop.stop_when_event_set(stop_event)
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,stop = stop_policy)
    def my_function():
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  8. tenacity.stop.stop_base:基类停止策略,用于自定义停止策略。
六、等待策略:tenacity.wait
  1. 自定义函数
    import tenacity
    import time
    
    def wait_fun(retry_state):
        print(retry_state)
        time.sleep(2)
        return True
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=wait_fun)
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  2. tenacity.wait.wait_fixed:等待策略,固定等待一段时间后再进行重试。
    import tenacity
    import time
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=tenacity.wait.wait_fixed(2))
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  3. tenacity.wait.wait_none:等待策略,无需等待,立即进行重试。
    import tenacity
    import time
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=tenacity.wait.wait_none())
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  4. tenacity.wait.wait_incrementing:等待策略,递增地等待一段时间后再进行重试。
    import tenacity
    import time
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=tenacity.wait.wait_incrementing(2))
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  5. tenacity.wait.wait_chain:等待策略,按照指定的等待策略链依次进行等待。
    import tenacity
    import time
    
    wait_chain = tenacity.wait.wait_chain(
        tenacity.wait.wait_fixed(2),
        tenacity.wait.wait_incrementing(2)
    )
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=wait_chain)
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  6. tenacity.wait.wait_combine:等待策略,将多个等待策略组合在一起,按照指定的组合方式进行等待。
    import tenacity
    import time
    
    wait_combine = tenacity.wait.wait_combine(
        tenacity.wait.wait_fixed(2),
        tenacity.wait.wait_incrementing(2)
    )
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=wait_combine)
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  7. tenacity.wait.wait_exponential:等待策略,指数增长地等待一段时间后再进行重试。
    import tenacity
    import time
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=tenacity.wait.wait_exponential(3))
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  8. tenacity.wait.wait_exponential_jitter:等待策略,指数增长地等待一段时间,并加入随机抖动后再进行重试。
    import tenacity
    import time
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=tenacity.wait.wait_exponential_jitter(3))
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  9. tenacity.wait.wait_random:等待策略,随机等待一段时间后再进行重试。
    import tenacity
    import time
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=tenacity.wait.wait_random())
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  10. tenacity.wait.wait_random_exponential:等待策略,随机指数增长地等待一段时间后再进行重试。
    import tenacity
    import time
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,wait=tenacity.wait.wait_random_exponential())
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  11. tenacity.wait.wait_base:基类等待策略,用于自定义等待策略。
七、重试条件:tenacity.retry
  1. 自定义函数
    import tenacity
    
    
    def retry_if_result_none(retry_state): 
        return retry_state is None #返回True,则重试
    
    @tenacity.retry(retry=retry_if_result_none)
    def my_function():
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  2. tenacity.retry_always:条件函数,始终进行重试,无论条件如何
    import tenacity
    
    @tenacity.retry(retry=tenacity.retry_always)
    def my_function():
       print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  3. tenacity.retry_never:条件函数,永不重试。
    import tenacity
    
    @tenacity.retry(retry=tenacity.retry_never)
    def my_function():
        print('重试代码') #返回True,则重试
        
    # 调用被装饰的函数
    my_function()
    
  4. tenacity.retry_if_result:条件函数,只有当函数返回指定值时才进行重试。
    import tenacity
    
    def check_result(retry_state):
        return True
    
    @tenacity.retry(retry=tenacity.retry_if_result(check_result))
    def my_function():
       print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  5. tenacity.retry_if_not_result:条件函数,只有当函数返回指定值时才不进行重试。
    import tenacity
    
    def check_result(retry_state):
        return False
    
    @tenacity.retry(retry=tenacity.retry_if_not_result(check_result))
    def my_function():
       print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  6. tenacity.retry_if_exception:条件函数,只有当抛出指定类型的异常时才进行重试。
    import tenacity
    import random
    
    @tenacity.retry(retry=tenacity.retry_if_exception(Exception))
    def my_function():
        nu = random.randint(1,10)
    
        try:
            if nu<5:
                raise Exception(f'报错,需要重试={nu}')
            else:
                print(f'重试结束={nu}')
        except Exception as e:
            # 处理异常
            print("错误信息:", e)
            raise
    
    my_function()
    
  7. tenacity.retry_if_exception_type:条件函数,只有当抛出指定类型的异常时才进行重试。
    import tenacity
    import random
    
    @tenacity.retry(retry=tenacity.retry_if_exception_type(Exception))
    def my_function():
        nu = random.randint(1,10)
        try:
            if nu<5:
                raise Exception(f'报错,需要重试={nu}')
            else:
                print(f'重试结束={nu}')
        except Exception as e:
            # 处理异常
            print("错误信息:", e)
            raise
    
    my_function()
    
  8. tenacity.retry_if_exception_type:条件函数,只有当抛出指定类型的异常时才进行重试。
    import tenacity
    import random
    
    @tenacity.retry(retry=tenacity.retry_if_not_exception_type(Exception))
    def my_function():
        nu = random.randint(1,10)
        try:
            if nu<5:
                raise Exception(f'报错,不需要重试={nu}')
            else:
                print(f'重试结束={nu}')
        except Exception as e:
            # 处理异常
            print("错误信息:", e)
            raise
    
    my_function()
    
  9. tenacity.retry_unless_exception_type:装饰器,除非抛出指定类型的异常,否则进行重试。
    import tenacity
    import random
    
    @tenacity.retry(retry=tenacity.retry_unless_exception_type(Exception))
    def my_function():
        nu = random.randint(1,10)
        try:
            if nu<5:
                raise Exception(f'报错,不需要重试={nu}')
            else:
                print(f'重试结束={nu}')
        except Exception as e:
            # 处理异常        
            print("错误信息:", e)
            raise
    my_function()
    
  10. tenacity.retry_any:条件函数,只要有任何一个条件函数返回 True,就进行重试。
  11. tenacity.retry_all:条件函数,要求所有条件函数都返回 True 才进行重试。
  12. tenacity.retry_if_exception_message:条件函数,只有当抛出指定异常消息的异常时才进行重试。
  13. tenacity.retry_if_not_exception_message:条件函数,只有当未抛出指定异常消息的异常时才进行重试。
  14. tenacity.retry_if_exception_cause_type:条件函数,只有当异常的原因是指定类型的异常时才进行重试。
八、重试之前执行的操作:tenacity.before
  1. tenacity.before.before_log:前置操作,用于在每次重试之前记录日志信息。
    import tenacity
    import time
    from loguru import logger
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,before=tenacity.before.before_log(logger, 'INFO'))
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
  2. tenacity.before.before_nothing:前置操作,不执行任何操作,即无操作。
    import tenacity
    import time
    
    def retry_if_result_none(retry_state):
        return True
    
    @tenacity.retry(retry=retry_if_result_none,before=tenacity.before.before_nothing)
    def my_function():
        print(time.time())
        print('重试代码')
    
    # 调用被装饰的函数
    my_function()
    
九、重试之后执行的操作:tenacity.after
  1. tenacity.after.after_log:后置操作,用于在每次重试之后记录日志信息。
  2. tenacity.after.after_nothing:后置操作,不执行任何操作,即无操作。
  3. tenacity.after.RetryCallState:重试调用状态对象,用于在重试过程中跟踪状态和信息。
十、等待之前执行的操作:tenacity.before_sleep
  1. tenacity.before_sleep.before_sleep_log:睡眠前操作,用于在每次重试之前记录日志信息。
  2. tenacity.before_sleep.before_sleep_nothing:睡眠前操作,不执行任何操作,即无操作。
十一、控制重试之间的等待时间:tenacity.nap
  1. tenacity.nap.sleep:这是 tenacity 库中默认的睡眠函数。它使用标准的时间模块进行睡眠,即使用 time.sleep 函数。
  2. tenacity.nap.sleep_using_event:这是另一种睡眠函数,它使用 eventlet 或 gevent 等协程库来实现睡眠。这种睡眠函数适用于在协程环境中使用 tenacity 库。
十二、重试状态对象:RetryCallState
  1. tenacity.RetryCallState():创建的 RetryCallState 实例
  • attempt_number:返回当前重试的次数(从1开始计数)。
  • delay_since_first_attempt:返回从首次重试开始经过的时间(以秒为单位)。
  • start_time:返回首次重试的时间戳(以秒为单位)。
  • outcome:返回最后一次重试的结果。如果重试尚未完成或未成功,该值为 None。
  • last_exception:返回最后一次重试时引发的异常。如果重试尚未完成或未引发异常,该值为 None。
  • initialize_time():将 start_time 设置为当前时间。
  • initialize_outcome(result):将 outcome 设置为给定的 result。
  • initialize_exception(exception):将 last_exception 设置为给定的 exception。
  • get_elapsed_time():返回从首次重试开始经过的时间(以秒为单位)。
  • get_attempt_number():返回当前重试的次数。
  • get_last_result():返回最后一次重试的结果。
  • get_last_exception():返回最后一次重试时引发的异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值