装饰器的两种实现方式
# 利用闭包实现def function_wrapper(wrapped): @functools.wraps(wrapped) def _wrapper(*args, **kwargs): return wrapped(*args, **kwargs) return _wrapper @function_wrapper def function(): pass # 类实现class function_wrapper(object): def __init__(self, wrapped): self.wrapped = wrapped def __call__(self, *args, **kwargs): return self.wrapped(*args, **kwargs) @function_wrapper def function(): pass # @ 带参数的情况def add_paras2_kws(*wargs,**wkws): print ("wargs:{}".format(wargs)) print ("wkws:{}".format(wkws)) def warp_f(f): @wraps(f) def dec(*fargs, **fkws): print(f) wkws.update(**fkws) print ("fargs:{}".format(fargs)) print ("fkws:{}".format(fkws)) return f(*fargs, **wkws) return dec return warp_f
示例一,retry
def __retry_internal(f, exceptions=Exception, tries=-1, delay=0, max_delay=None, backoff=1, jitter=0, logger=logging_logger): """ Executes a function and retries it if it failed. :param f: 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. """ _tries, _delay = tries, delay while _tries: try: return f() except exceptions as e: _tries -= 1 if not _tries: raise if logger is not None: logger.warning('%s, retrying in %s seconds...', e, _delay) time.sleep(_delay) _delay *= backoff if isinstance(jitter, tuple): _delay += random.uniform(*jitter) else: _delay += jitter if max_delay is not None: _delay = min(_delay, max_delay)def retry(exceptions=Exception, tries=-1, delay=0, max_delay=None, backoff=1, jitter=0, logger=logging_logger): """Returns a retry decorator. :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: a retry decorator. """ @decorator def retry_decorator(f, *fargs, **fkwargs): args = fargs if fargs else list() kwargs = fkwargs if fkwargs else dict() return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter, logger) return retry_decorator
comments:
__retry_internal 调用前先固定住f的参数,简化问题。
__retry_internal 要处理的只有f的调用执行。
示例二
from functools import wrapsdef return_kw(**kw): return kwdef add_paras2_kws(*wargs,**wkws): print ("wargs:{}".format(wargs)) print ("wkws:{}".format(wkws)) def warp_f(f): @wraps(f) def dec(*fargs, **fkws): print(f) wkws.update(**fkws) print ("fargs:{}".format(fargs)) print ("fkws:{}".format(fkws)) return f(*fargs, **wkws) return dec return warp_f@add_paras2_kws(7,8,9,a=80,b=81,c=82,d=83)def test_b(*args,**kw): return return_kw(**kw)if __name__ == '__main__': print(test_b(1,2,3,a=4,b=5))
comments:
要在常规的装饰器外再套一层接收参数,因为是先传递@的参数,接着传递被装饰的函数,再传递被装饰函数的参数。
作者:一只老梨花
链接:https://www.jianshu.com/p/44b654fc8f14
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦