Python3,它,会魔法吧,来自最强大的错误重试库。

举报
Carl_奕然 发表于 2023/03/17 16:00:37 2023/03/17
【摘要】 有了此库,我还要什么 try .... except...

1、 引言


小云:鱼哥,最近遇到点问题。
小鱼:呦呵,你这是遇到的问题不小啊,不然不能主动跟我说。
小云:唉~~ 在试错的路上,越走越迷茫。
小鱼:那是因为你没有用对方法啊。
小云:这个还有方法?
小鱼:这你就不懂了吧。

在这里插入图片描述

小云:那你快快教教我哦~ ~
小鱼:retry 你可以了解一下。
小云:retry用法单一,不符合我的要(wei)求(kou)。
小鱼:那你就试一试tenacity
小云:不会,你教我啊。
小鱼:… 这又是赔本的一天。

2、 tenacity


我们在调用web接口,或者爬虫的时候,经常会遇到一些偶发请求失败的状况,这个时候,我们可能会想到一直循环尝试直到成功;或者打出错误信息;
这种做法,在简单的程序中没有错,但是,在复杂的或者大型项目中,这种做法显然有很多弊端。
而我们需要用到一个错误重试方法,老鸟应该会想到是tenactiy。
没错,tenacity可能目前是python中最好的第三方重试库,
接下来,我们就来一睹它的风采。

2.1 安装


作为第三方库,我们第一步必须是 安装

老规矩, pip方式安装:

pip install tenacity

其它安装方式,直接看这两篇:

2.2 基本用法


tenacity的错误重试核心功能由其retry装饰器来实现,
默认不给retry装饰器传参数时,它会在其所装饰的函数运行过程抛出错误不时停地重试下去。

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

import random
from tenacity import retry

@retry
def demo_one():
    a = random.random()
    print(f'{a}')
    
    if a >= 0.1:
        raise Exception
demo_one()



运行结果

在这里插入图片描述

通过结果,可以看到,函数体内每次生成0到1之间的随机数,当这个随机数不超过0.1时才会停止抛出错误,否则则会被tenacity捕捉到每次的错误抛出行为并立即重试。

2.3 重试最大次数


由于我们的时间是宝贵的,所以重试的次数也需要有限制的。

我们可以利用tenacity中的stop_after_attempt函数,作为retry()中的stop参数传入,从而为我们“无尽”的错误重试过程添加一个终点,
其中**stop_after_attempt()**接受一个整数输入作为"最大重试"的次数:

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

from tenacity import retry,stop_after_attempt

#设置错误重试,3次
@retry(stop = stop_after_attempt(3))

def demo_two():
    print(f'函数执行')

    raise  Exception

demo_two()



运行结果

在这里插入图片描述

通过结果,可以看到,在第4次继续执行正式地抛出了函数中对应的Exception错误结束了重试过程。

2.4 重试最长时间


除了设置错误的次数,还可以设置最大的重试耗时,
通过stop_after_delay() 的函数来设置,超过这个时长就会结束重试过程。

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

import  time
from tenacity import  retry,stop_after_delay

#设置重试最大超时时长为4秒
@retry(stop = stop_after_delay(4))

def demo_three():
    #每次时间间隔为2秒
    time.sleep(2)
    print(f'已过去 {time.time() - start_time} 秒')
    raise  Exception

start_time = time.time()
demo_three()


运行结果

在这里插入图片描述

2.5 组合重试停止条件

如果同时需要添加最大重试次数以及最大超时时长限制,
在tenacity中仅需要用 | 运算符组合不同的限制条件再传入retry()的stop参数即可,

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

import  time
import random
from tenacity import retry,stop_after_attempt,stop_after_delay

#函数执行重试超过3秒或次数大于5次时均可以结束重试
@retry(stop =(stop_after_attempt(3) | stop_after_delay(5)))
def  demo_four():
    time.sleep(random.random())
    print(f'已过去 {time.time() - start_time} 秒')

    raise Exception

#开始时间
start_time = time.time()
demo_four()



运行结果

在这里插入图片描述

2.6 相邻重试时间间隔

tenacity中提供了一系列非常实用的函数,配合retry()的wait参数,帮助我们妥善处理相邻重试之间的时间间隔,其中较为实用的主要有以下两种方式:

  • 固定时间间隔;
  • 随机时间间隔;


2.6.1 固定时间间隔


使用tenacity中的**wait_fixed()**可以为相邻重试之间设置固定的等待间隔秒数

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

import time
from tenacity import  retry,wait_fixed,stop_after_attempt

# 设置重试等待间隔为1秒
@retry(wait = wait_fixed(1),stop = stop_after_attempt(3))
def demo_five():
    print(f'已过去 {time.time() - start_time} 秒')

    raise  Exception
#开始时间
start_time = time.time()
demo_five()



运行结果

在这里插入图片描述

2.6.2 随机时间间隔

除了设置固定的时间间隔外,tenacity还可以通过**wait_random()**为相邻重试设置均匀分布随机数,只需要设置好均匀分布的范围即可:

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

import time
from tenacity import  retry,wait_random,stop_after_attempt

# 设置重试等待间隔为1到3之间的随机数
@retry(wait = wait_random(min=1,max=3),stop = stop_after_attempt(4))
def demo_six():
    print(f'已过去 {time.time() - start_time} 秒')

    raise  Exception
#开始时间
start_time = time.time()
demo_six()



运行结果

在这里插入图片描述

2.7 自定义是否触发重试

tenacity中retry()的默认策略是当其所装饰的函数执行过程“抛出任何错误”时即进行重试,
但有些情况下需要的可能是对特定错误类型的捕捉/忽略,亦或是对异常计算结果的捕捉。
tenacity中同样内置了相关的实用功能:

  • 捕捉或忽略特定的错误类型;
  • 自定义函数结果条件判断函数;


2.7.1 忽略特定错误类型


使用tenacity中的retry_if_exception_type()和retry_if_not_exception_type(),配合retry()的retry参数,对特定的错误类型进行捕捉或忽略:

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

'''
捕捉或忽略特定的错误类型
'''
from tenacity import retry,retry_if_exception_type,retry_if_not_exception_type

#retry_if_exception_type()
@retry(retry=retry_if_exception_type(FileExistsError))
def demo_seven():
    raise TimeoutError

demo_seven()

#retry_if_not_exception_type()
@retry(retry=retry_if_not_exception_type(FileNotFoundError))
def demo_eight():
    raise FileNotFoundError

demo_eight()



运行结果

demo_seven()

在这里插入图片描述

demo_eight()

在这里插入图片描述
2.7.2 自定义函数结果条件判断函数


我们可以编写额外的条件判断函数,配合tenacity中的retry_if_result(),实现对函数的返回结果进行自定义条件判断,返回True时才会触发重试操作:

代码示例

# -*- coding:utf-8 -*-
# @Time   : 2022-04-04
# @Author : carl_DJ

import  random
from tenacity import  retry,retry_if_result

@retry(retry = retry_if_result(lambda x: x >= 0.1))
def demo_nine():
    a =  random.random()
    print(f'{a}')
    return a

demo_nine()


运行结果

在这里插入图片描述
3、总结


今天的分享,就到这里了。
是不是奇奇怪怪的姿势,又增加了呢。
在错误的重试姿势,也增加了。

我是​小鱼​:

  • CSDN 博客专家;
  • 阿里云 专家博主;
  • 51CTO 博客专家;
  • 51认证讲师;
  • 金牌面试官&面试培训师;

关注我,带你学习更多更有趣的Python知识。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。