加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python retry异常重试模块 函数报错时重新执行

发布时间:2020-12-17 16:59:59 所属栏目:Python 来源:网络整理
导读:背景: 我们经常遇到一个场景,就是如果操作失败则需要多次重试某些操作,这种情况下,如果想优雅的实现功能,又不关心重试逻辑,则可以学习该模块。 介绍 retry是一个 Python的重试包,可以用来自动重试一些可能运行失败的程序段。retrying提供一个装饰器函

背景:

我们经常遇到一个场景,就是如果操作失败则需要多次重试某些操作,这种情况下,如果想优雅的实现功能,又不关心重试逻辑,则可以学习该模块。

介绍

retry是一个 Python的重试包,可以用来自动重试一些可能运行失败的程序段。retrying提供一个装饰器函数retry,被装饰的函数就会在运行失败的条件下重新执行,默认只要一直报错就会不断重试。

安装

pip?install?retry

官方网址

https://pypi.python.org/pypi/retry

API 介绍

retry decorator

def?retry(exceptions=Exception,?tries=-1,?delay=0,?max_delay=None,?backoff=1,?jitter=0,?logger=logging_logger):
????"""Return?a?retry?decorator.

????:param?exceptions:捕获异常或异常元组。?默认:Exception。
????:param?tries:Exception最大尝试次数。?默认值:-1(无限)。
????:param?delay:尝试之间的初始延迟。?默认值:0。
????:param?max_delay:延迟的最大值。?默认值:无(无限制)。
????:param?backoff:乘法器应用于尝试之间的延迟。?默认值:1(无退避)。
????:param?jitter:额外的秒数添加到尝试之间的延迟。?默认值:0。
???????????????如果数字固定,则随机如果范围元组(最小值,最大值)
????:param?logger:logger.warning(fmt,error,delay)将在失败尝试中调用。
????????????????????默认值:retry.logging_logger。?如果无,则记录被禁用。
????"""

使用:

1.不带参数

from?retry?import?retry

@retry()
def?make_trouble():
????'''Retry?until?succeed'''
????print?('retrying...')
????raise

if?__name__?==?'__main__':
????make_trouble()

#?输出:?一直重试,直到运行成功
retrying...
retrying...
retrying...
retrying...
retrying...
retrying...

2.Exception参数, 默认 Exception,只捕获重试指定的异常,可以是元组

@retry(ZeroDivisionError,?tries=3,?delay=2)
def?make_trouble():
????'''Retry?on?ZeroDivisionError,?raise?error?after?3?attempts,?sleep?2?seconds?between?attempts.'''
????print?'aaa'
????a?=?1/0

if?__name__?==?'__main__':
????make_trouble()

输出:
aaa
aaa
Traceback?(most?recent?call?last):
??File?"E:/WORKSPACE/document/document/test/1.py",?line?20,?in?<module>
????make_trouble()
??File?"<decorator-gen-2>",?line?2,?in?make_trouble
??File?"D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py",?line?74,?in?retry_decorator
????logger)
??File?"D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py",?line?33,?in?__retry_internal
????return?f()
??File?"E:/WORKSPACE/document/document/test/1.py",?line?16,?in?make_trouble
????a?=?1/0
ZeroDivisionError:?integer?division?or?modulo?by?zero
aaa

3.backoff参数,尝试间隔时间,成倍数增加

import?time
@retry((ValueError,?TypeError),?delay=1,?backoff=2)
def?make_trouble():
????'''Retry?on?ValueError?or?TypeError,?sleep?1,?2,?4,?8,?...?seconds?between?attempts.'''
????print?(1,??int(time.time()))

????raise?ValueError('a')

if?__name__?==?'__main__':
????make_trouble()

输出:
(1,?1504107288)
(1,?1504107289)
(1,?1504107291)
(1,?1504107295)
(1,?1504107303)
(1,?1504107319)
(1,?1504107351)

4.max_delay 指定最大间隔时间,backoff参数触发的休眠时间大于max_delay时,休眠时间以max_delay为准则

import?time

@retry((ValueError,?backoff=2,?max_delay=8)
def?make_trouble():
????'''Retry?on?ValueError?or?TypeError,?...?seconds?between?attempts.'''

????print?(1,?int(time.time()))
????raise?ValueError('aa')


if?__name__?==?'__main__':
????make_trouble()

输出:
(1,?1504107496)
(1,?1504107497)
(1,?1504107499)
(1,?1504107503)
(1,?1504107511)
(1,?1504107519)
(1,?1504107527)
(1,?1504107535)

5.jitter参数,累加,以及异常触发的日志

import?time

@retry(ValueError,?jitter=1)
def?make_trouble():
????'''Retry?on?ValueError,?3,?int(time.time()))
????raise?ValueError('e')

if?__name__?==?'__main__':
????import?logging
????logging.basicConfig()
????make_trouble()

输出:
WARNING:retry.api:e,?retrying?in?1?seconds...
(1,?1504107644)
WARNING:retry.api:e,?retrying?in?2?seconds...
(1,?1504107645)
WARNING:retry.api:e,?retrying?in?3?seconds...
(1,?1504107647)
WARNING:retry.api:e,?retrying?in?4?seconds...
(1,?1504107650)
WARNING:retry.api:e,?retrying?in?5?seconds...
(1,?1504107654)
WARNING:retry.api:e,?retrying?in?6?seconds...
(1,?1504107659)
(1,?1504107665)
WARNING:retry.api:e,?retrying?in?7?seconds...
(1,?1504107672)
WARNING:retry.api:e,?retrying?in?8?seconds...

retry_call

def?retry_call(f,?fargs=None,?fkwargs=None,?exceptions=Exception,?logger=logging_logger):?
“””?
Calls?a?function?and?re-executes?it?if?it?failed.
:param?f:?the?function?to?execute.
:param?fargs:?the?positional?arguments?of?the?function?to?execute.
:param?fkwargs:?the?named?arguments?of?the?function?to?execute.
:param?exceptions:?an?exception?or?a?tuple?of?exceptions?to?catch.?default:?Exception.
:param?tries:?the?maximum?number?of?attempts.?default:?-1?(infinite).
:param?delay:?initial?delay?between?attempts.?default:?0.
:param?max_delay:?the?maximum?value?of?delay.?default:?None?(no?limit).
:param?backoff:?multiplier?applied?to?delay?between?attempts.?default:?1?(no?backoff).
:param?jitter:?extra?seconds?added?to?delay?between?attempts.?default:?0.
???????????????fixed?if?a?number,?random?if?a?range?tuple?(min,?max)
:param?logger:?logger.warning(fmt,?error,?delay)?will?be?called?on?failed?attempts.
???????????????default:?retry.logging_logger.?if?None,?logging?is?disabled.
:returns:?the?result?of?the?f?function.
"""

例子

import?requests
from?retry.api?import?retry_call

def?make_trouble(service,?info=None):
????if?not?info:
????????info?=?''
????print?('retry...,?service:?{},??info:?{}'.format(service,?info))
????r?=?requests.get(service?+?info)
????print?r.text
????raise?Exception('info')

def?what_is_my_ip(approach=None):
????if?approach?==?"optimistic":
????????tries?=?1
????elif?approach?==?"conservative":
????????tries?=?3
????else:
????????#?skeptical
????????tries?=?-1
????result?=?retry_call(make_trouble,?fargs=["http://ipinfo.io/"],?fkwargs={"info":?"ip"},?tries=tries)
????print(result)

if?__name__?==?'__main__':
????import?logging
????logging.basicConfig()
????what_is_my_ip("conservative")


输出:
retry...,?service:?http://ipinfo.io/,??info:?ip
118.113.1.255

retry...,??info:?ip
WARNING:retry.api:info,?retrying?in?0?seconds...
WARNING:retry.api:info,?retrying?in?0?seconds...
118.113.1.255

retry...,??info:?ip
Traceback?(most?recent?call?last):
??File?"E:/WORKSPACE/document/document/test/1.py",?in?<module>
????what_is_my_ip("conservative")
??File?"E:/WORKSPACE/document/document/test/1.py",?line?66,?in?what_is_my_ip
????result?=?retry_call(make_trouble,?tries=tries)
??File?"D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py",?line?101,?in?retry_call
????return?__retry_internal(partial(f,?*args,?**kwargs),?exceptions,?tries,?delay,?max_delay,?backoff,?jitter,?logger)
??File?"D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py",?line?54,?in?make_trouble
????raise?Exception('info')
Exception:?info
118.113.1.255

参考:https://blog.csdn.net/ricky110/article/details/77727397


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读