以抛出异常重试为例。
前言
具体的理解可以参考https://www.runoob.com/w3cnote/python-func-decorators.html
讲得挺明白的。
装饰器的本质是一个函数或者类。
为了方便记忆与理解,我将它记为C/C++里面类似define的语法糖(但实质比这更复杂)。
举例如下:
@xxx
def func(*arg, **kwargs):
pass
'''
以下两种运行方法等同
result = func("若干参数")
result = xxx(func)("若干参数")
上述xxx可以是函数实现dec_fun
也可以是带参数的函数实现dec_fun(*arg, **kwargs)
还可以是类实现dec_class(*arg, **kwargs)
总之,xxx这一坨需要实现一个功能,即写法xxx(func)返回一个函数,该函数大体输入输出应该与func一致
'''
示例代码
# coding=utf-8
import requests
import time
from functools import wraps
def retry(func):
retry = 3
sleep = 1
def checkRun(retry, *args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
if(retry == 0):
raise e
else:
time.sleep(sleep)
return checkRun(retry-1, *args, **kwargs)
@wraps(func)
def run(*args, **kwargs):
return checkRun(retry, *args, **kwargs)
return run
def retryWithParam(retry = 3, sleep = 1):
def decoratedRetry(func):
def checkRun(retry, *args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
if(retry == 0):
raise e
else:
time.sleep(sleep)
return checkRun(retry-1, *args, **kwargs)
@wraps(func)
def run(*args, **kwargs):
return checkRun(retry, *args, **kwargs)
return run
return decoratedRetry
class retryWithClass(object):
def __init__(self, retry = 3, sleep = 1):
self.retry = retry
self.sleep = sleep
def __call__(self, func):
def checkRun(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
if(self.retry == 0):
raise e
else:
self.retry -= 1
time.sleep(self.sleep)
return checkRun(*args, **kwargs)
@wraps(func)
def run(*args, **kwargs):
return checkRun(*args, **kwargs)
return run
#@retry
#@retryWithParam(retry = 2)
#@retryWithClass(retry = 1)
def do_something(param = 1):
print("do_something")
return param
@retry
#@retryWithParam(retry = 2)
#@retryWithClass(retry = 1)
def do_error(param = 1):
print("do_error")
1/0
return param
if __name__ == '__main__':
result = do_error("decoratedRetry")
print(result)
#retry(do_something)(参数)
func1 = retry(do_something)
result = func1("retry")
print(result)
#retryWithParam(retry = 2)(do_something)(参数)
func2 = retryWithParam(retry = 2)(do_something)
result = func2("retryWithParam")
print(result)
#retryWithClass(retry = 1)(do_something)(参数)
func3 = retryWithClass(retry = 1)(do_something)
result = func3("retryWithClass")
print(result)