"""
Version: 0.1
Author: freshbin
Date: 2019年8月22日
"""
print("=================================装饰器 start================================================")
from time import sleep
from functools import wraps
import logging
logging.basicConfig() #好像是不保存日志文件,直接在控制台打印
log = logging.getLogger("retry")
def retry(f):
@wraps(f)
def wrapped_f(*args, **kwargs):
MAX_ATTEMPTS = 5
for attempt in range(1, MAX_ATTEMPTS + 1):
try:
return f(*args, **kwargs)
except:
log.exception("Attempt %s/%s failed : %s",
attempt,
MAX_ATTEMPTS,
(args, kwargs))
sleep(2)
print("All %s attempts failed : %s",
MAX_ATTEMPTS,
(args, kwargs))
log.critical("All %s attempts failed : %s",
MAX_ATTEMPTS,
(args, kwargs))
return wrapped_f
counter = 0
@retry
def save_to_database(arg):
global counter
counter += 1
print("第{}次运行save_to_database.".format(counter))
print("Write to a database or make a network call or etc.")
print("This will be automatically retried if exception is thrown.")
# 这将第一次调用时抛出异常
# 在第二次运行时将正常工作(也就是重试)
if counter < 2:
raise ValueError(arg)
return "save_to_database成功运行完毕."
if __name__ == '__main__':
print(save_to_database("Some bad value"))
'''
照着代码打完,发现看不懂这个程序怎么运行
后来查了资料,感觉装饰器作用是把一个本来要调用的函数给拦截
然后在定义的装饰器中调用原来要调用的函数
见https://www.jb51.net/article/158814.htm
这个例子还加入了@wraps
因为被装饰器装饰过的函数,__doc__和__name__等信息都会变为装饰函数里面定义的那个函数信息
所以@wraps这个注解能把被装饰函数的基本信息还原成其自身
见https://www.jianshu.com/p/a76f1409c349
'''
print("=================================装饰器 end================================================")