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

1、 引言

小屌丝:鱼哥,最近遇到点问题。
小鱼:呦呵,你这是遇到的问题不小啊,不然不能主动跟我说。
小屌丝:唉~~ 在试错的路上,越走越迷茫。
小鱼:那是因为你没有用对方法啊。
小屌丝:这个还有方法?
小鱼:这你就不懂了吧。
在这里插入图片描述
小屌丝:那你快快教教我哦~ ~
小鱼:retry 你可以了解一下。
小屌丝:retry用法单一,不符合我的要(wei)求(kou)。
小鱼:那你就试一试tenacity
小屌丝:不会,你教我啊。
小鱼:… 这又是赔本的一天。

2、 tenacity

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

2.1 安装

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

pip install tenacity

其他方式安装

Python3,选择Python自动安装第三方库,从此跟pip说拜拜!!
Python3:我低调的只用一行代码,就导入Python所有库!!

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、总结

今天的分享,就到这里了。
是不是奇奇怪怪的姿势,又增加了呢。
在错误的重试姿势,也增加了。
关注小鱼,学习更多关于python第三方库的知识。

猜你喜欢

转载自blog.csdn.net/wuyoudeyuer/article/details/123911975