Python decorator 记录
前言
简单记录,不断更新。
提示:以下是本篇文章正文内容,下面案例可供参考
一、decorator简介
decorator 本质是一个函数,与其他函数不同的是,它的的入参也是一个函数,返回值是一个对象,可以让其他函数在不增加代码的前提下增加额外功能。
二、应用场景
插入日志,计算运行时间,事物处理。 有了decorator,可以抽离出大量与函数功能本身无关的雷同代码。
三、分类
函数decorator和类decorator
四、基本使用
1. 基础使用
case1: 记录一个函数执行所需时间 original code:
def func1():
startTime = time.time()
print("this is func1")
time.sleep(2)
execTime = time.time()-startTime
print("total exec time %s." % execTime)
如果想要记录一百个函数的执行时间,会有大量雷同代码。因此,使用decorator now:
def timeCalc(func):
def wrapper():
startTime = time.time()
func()
execTime = time.time()-startTime
print("%s exec need time %s" %(func.__name__, execTime))
return wrapper
@timeCalc
def fun3():
time.sleep(3)
@timeCalc
def fun4():
time.sleep(4)
2. 带参数的decorator
def timeCalc(func):
def wrapper(*args, **kwargs):
startTime = time.time()
func(*args, **kwargs)
execTime = time.time()-startTime
print("%s exec need time %s" %(func.__name__, execTime))
return wrapper
@timeCalc
def funcAdd(x, y):
print('x + y = ', x+y)
time.sleep(1)
@timeCalc
def funcAddMore(x, y, z):
print('x + y + z = ', x+y+z)
time.sleep(2)
3. decorator本身可以带para
def timeCalc(level):
def outWrapper(func):
def wrapper(*args, **kwargs):
startTime = time.time()
func(*args, **kwargs)
execTime = time.time()-startTime
print("%s %s exec need time %s" %(level, func.__name__, execTime))
return wrapper
return outWrapper
@timeCalc(level="info")
def funcAdd2(x, y):
print('x + y = ', x+y)
time.sleep(1)
@timeCalc(level="debug")
def funcAddMore2(x, y, z):
print('x + y + z = ', x+y+z)
time.sleep(2)
funcAdd2(1,2)
funcAddMore2(1,2,3)
4. 实际使用
background: try-catch 的使用降低代码的可读性,使用decorator 减少try-catch. 当func抛出异常时,decorator默认catch exception.
DEFAULT_FAULT_KEY = "defaultKey"
def RunTaskFunc(taskFunc, fault, funName):
logger.error("output all kinds of info %s %s" % (fault, funName))
try:
taskFunc()
except Exception as e:
logger.exception("exception")
def taskGuard(fault=DEFAULT_FAULT_KEY):
def inner(func):
@functools.wraps(func)
def wrapper(task, **kwargs):
RunTaskFunc(lambda: func(task, **kwargs),
fault, func.__name__)
return wrapper
return inner
@taskGuard(fault="commonFuncKey")
def commonFunc(task="task"):
a = 1/0
return
commonFunc(task="commonFuncTask")
|