简单实现了一个在函数执行出现异常时自动重试的装饰器,支持控制最多重试次数,每次重试间隔,每次重试间隔时间递增。

最新的代码可以访问从github上获取

https://github.com/blackmatrix7/matrix-toolkit/blob/master/toolkit/retry.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017/8/18 上午9:50
# @Author : Matrix
# @Github : https://github.com/blackmatrix7/
# @Blog : http://www.cnblogs.com/blackmatrix/
# @File : retry.py
# @Software: PyCharm
import time
from functools import wraps __author__ = 'blackmatrix' """
在函数执行出现异常时自动重试的简单装饰器
""" class StopRetry(Exception): def __repr__(self):
return 'retry stop' def retry(max_retries: int =5, delay: (int, float) =0, step: (int, float) =0,
exceptions: (BaseException, tuple, list) =BaseException,
sleep=time.sleep, callback=None, validate=None):
"""
函数执行出现异常时自动重试的简单装饰器。
:param max_retries: 最多重试次数。
:param delay: 每次重试的延迟,单位秒。
:param step: 每次重试后延迟递增,单位秒。
:param exceptions: 触发重试的异常类型,单个异常直接传入异常类型,多个异常以tuple或list传入。
:param sleep: 实现延迟的方法,默认为time.sleep。
在一些异步框架,如tornado中,使用time.sleep会导致阻塞,可以传入自定义的方法来实现延迟。
自定义方法函数签名应与time.sleep相同,接收一个参数,为延迟执行的时间。
:param callback: 回调函数,函数签名应接收一个参数,每次出现异常时,会将异常对象传入。
可用于记录异常日志,中断重试等。
如回调函数正常执行,并返回True,则表示告知重试装饰器异常已经处理,重试装饰器终止重试,并且不会抛出任何异常。
如回调函数正常执行,没有返回值或返回除True以外的结果,则继续重试。
如回调函数抛出异常,则终止重试,并将回调函数的异常抛出。
:param validate: 验证函数,用于验证执行结果,并确认是否继续重试。
函数签名应接收一个参数,每次被装饰的函数完成且未抛出任何异常时,调用验证函数,将执行的结果传入。
如验证函数正常执行,且返回False,则继续重试,即使被装饰的函数完成且未抛出任何异常。
如回调函数正常执行,没有返回值或返回除False以外的结果,则终止重试,并将函数执行结果返回。
如验证函数抛出异常,且异常属于被重试装饰器捕获的类型,则继续重试。
如验证函数抛出异常,且异常不属于被重试装饰器捕获的类型,则将验证函数的异常抛出。
:return: 被装饰函数的执行结果。
"""
def wrapper(func):
@wraps(func)
def _wrapper(*args, **kwargs):
nonlocal delay, step, max_retries
func_ex = StopRetry
while max_retries > 0:
try:
result = func(*args, **kwargs)
# 验证函数返回False时,表示告知装饰器验证不通过,继续重试
if callable(validate) and validate(result) is False:
continue
else:
return result
except exceptions as ex:
# 回调函数返回True时,表示告知装饰器异常已经处理,终止重试
if callable(callback) and callback(ex) is True:
return
func_ex = ex
finally:
max_retries -= 1
if delay > 0 or step > 0:
sleep(delay)
delay += step
else:
raise func_ex
return _wrapper
return wrapper if __name__ == '__main__':
pass

python重试装饰器的简单实现的更多相关文章

  1. Python:装饰器的简单理解

    1.装饰器的本质是函数,主要用来装饰其他函数,也就是为其他函数添加附加功能 2.装饰器的原则: (1) 装饰器不能修改被装饰的函数的源代码 (2) 装饰器不能修改被装饰的函数的调用方式 3.实现装饰器 ...

  2. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  3. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  4. 详解Python的装饰器

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  5. 关于python的装饰器(初解)

    在python中,装饰器(decorator)是一个主要的函数,在工作中,有了装饰器简直如虎添翼,许多公司面试题也会考装饰器,而装饰器的意思又很难让人理解. python中,装饰器是一个帮函数动态增加 ...

  6. python之装饰器(decorator)

    python的装饰器如果用得好,那是大神,用的不好最好别用... 装饰器(decorator)主要包含俩大属性: 1.不能改变原有函数的调用方式 2.不能改变原有函数的代码 第一个表示,我不需要改变原 ...

  7. 【转】Python之装饰器

    [转]Python之装饰器 本节内容 必要知识回顾 情景模拟 装饰器的概念及实现原理 回马枪(带参数的装饰器) 一. 必要知识回顾 在开始说装饰器之前,需要大家熟悉之前说过的相关知识点: 函数即“变量 ...

  8. python异常装饰器--比较全的版本了

    # 异常捕获装饰器(亦可用于类方法) def try_except_log(f=None, max_retries: int = 5, delay: (int, float) = 1, step: ( ...

  9. 【转】【Python】装饰器

    1.闭包 >>> def outer(): ... x = 1 ... def inner(): ... ... return inner >>> foo = ou ...

随机推荐

  1. 原生Js实现拖拽(适用于pc和移动端)

    效果: HTML和CSS部分 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  2. Scala入门系列(九):函数式编程

    引言 Scala是一门既面向对象,又面向过程的语言,Scala的函数式编程,就是Scala面向过程最好的佐证.也真是因此让Scala具备了Java所不具备的更强大的功能和特性. 而之所以Scala一直 ...

  3. 前端备忘录--JQuery选择器

    基本选择器 基本选择器是最常用的选择器,也是最简单的选择器. $("#test") //选取id为test的元素 $(".test") //选取class为te ...

  4. python爬虫(六)_urllib2:handle处理器和自定义opener

    本文将介绍handler处理器和自定义opener,更多内容请参考:python学习指南 opener和handleer 我们之前一直使用的是urllib2.urlopen(url)这种形式来打开网页 ...

  5. B. Simple Game( Codeforces Round #316 (Div. 2) 简单题)

    B. Simple Game time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  6. oracle 10g下范围分区扫描的几种方式

    oracle 10g下有几种扫描方式,注意最后一种扫描方式,当对分区的列进行计算时,会不走分区.这跟对索引列进行计算会导致无法用索引一样. --扫描单个分区  PARTITION RANGE SING ...

  7. 中颖内带LED资源驱动代码

    //上一篇写了LCD驱动,本篇写下LED驱动 //DISPCON 最高位为1时, 选择LED驱动,LCD驱动无效 最高位为0时, 选择LCD驱动.LED驱动无效 void Sh79fLed_Init( ...

  8. html5视频标签

    <video width="200" height="200" poster="img/shamo.jpg" src="vi ...

  9. jersey框架实现文件上传

    jersey框架是一个开源的RESTful的框架,实现了实现了JAX-RS规范,进一步地简化 RESTful service 和 client 开发.当然而且是必须的,jersey对文件的上传和下载也 ...

  10. 关于MySql中使用IFNULL()函数失效的问题。

    今天在学习时,碰到一个问题:在联表查询取得结果后,如果取得的结果是空值,则给一个默认值,如果不是空值,则返回这个值. 下面我们来看看业务场景: 在menu表中: 存储的是前端页面的菜单配置,注意成员权 ...