案例一:(使用自建的属性装饰器)
import datetime
import time
def copy_attributes(src):
def wrapper(dst):
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
return dst
return wrapper
def outer(t1,t2,func=lambda name,duration:print("funciton:{} tooks {} seconds".format(name,duration))): #此处lambda函数为打印到控制台,可以替换为写入数据库或者写入日志文件等函数
def logger(fn):
@copy_attributes(fn) #_logger = copy_attributes(fn)(_logger) ==> _logger = wrapper(_logger) ==> _logger=dst
def _logger(*args,**kwargs):
'''
this is a wrapper function
'''
print('before')
start = datetime.datetime.now()
ret = fn(*args,**kwargs)
stop = datetime.datetime.now()
duration = (stop-start).total_seconds()
if duration > t1 and duration < t2:
func(fn.__name__,duration)
# print("funciton:{} tooks {} seconds".format(fn.__name__,duration))
print('after')
return ret
return _logger
return logger
@outer(3,10) #@outer等价于add = outer(add),此处的add为@的下一行中第一个函数
def add(x,y):
'''
This is a function for addtion
:param x: int
:param y: int
:return: int
'''
time.sleep(6)
return x+y
print(1,add(4,5))
print(2,add.__name__)
print(3,add.__doc__)
运行结果:
before
funciton:add tooks 6.006787 seconds
after
1 9
2 add
3
This is a function for addtion
:param x: int
:param y: int
:return: int
案例变形:(使用内建functools的属性装饰器)
import datetime
import time
import functools
def outer(t1,t2,func=lambda name,duration:print("funciton:{} tooks {} seconds".format(name,duration))):
def logger(fn):
@functools.wraps(fn)
def _logger(*args,**kwargs):
'''
this is a wrapper function
'''
print('before')
start = datetime.datetime.now()
ret = fn(*args,**kwargs)
stop = datetime.datetime.now()
duration = (stop-start).total_seconds()
if duration > t1 and duration < t2:
func(fn.__name__,duration)
# print("funciton:{} tooks {} seconds".format(fn.__name__,duration))
print('after')
return ret
print("wrapper_id:{} wrapped_id:{}".format(id(_logger),id(fn)))
return _logger
return logger
@outer(3,10) #@outer等价于add = outer(add),此处的add为@的下一行中第一个函数
def add(x,y):
'''
This is a function for addtion
:param x: int
:param y: int
:return: int
'''
time.sleep(6)
return x+y
print(1,add(4,5))
print(2,add.__name__)
print(3,add.__doc__)
print(4,'src_id',id(add.__wrapped__))
运行结果:
wrapper_id:140039781061496 wrapped_id:140039781061360
before
funciton:add tooks 6.0019 seconds
after
1 9
2 add
3
This is a function for addtion
:param x: int
:param y: int
:return: int
4 src_id 140039781061360 #可以看出wrapped_id == src_id,所以原始的函数被functools.wraps属性装饰器保留了,使用__wrapped__即可访问