如题
import time, functools
def log(func):
@functools.wraps(func) #可以尝试把这个装饰器去掉,会导致func的函数名被改了
def wrapper(*args, **kw): #如果写成args, kw,那么函数test(x=3,y=4就废了)
# 因为返回的那个wrapper()
# 函数名字就是'wrapper',所以,需要把原始函数的__name__等属性复制到wrapper()
# 函数中,否则,有些依赖函数签名的代码执行就会出错。
# 不需要编写wrapper.__name__ = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:
t1 = time.time()
r = func(*args, **kw) #对于*args, **kw的输入,一定也要这样调用才行
print('%s with paras tuple %s dic %s excute in %s ms' % (func.__name__, args, kw, 1000 * (time.time() - t1)))
return r
return wrapper #整个装饰器简单来说就是输入个函数,返回一个函数
@log
def test(x, y):
return x * y
def test1(x, y):
return x * y
print(test(x=3,y=4))
print('test.__name__ = {}'.format(test.__name__))
print('------------------------')
print(log(test1)(x=3,y=4)) #这和上面带着直接带着@log的效果是一样的
print('test1.__name__ = {}'.format(test1.__name__))
'''
输出:
test with paras tuple () dic {'x': 3, 'y': 4} excute in 0.0011920928955078125 ms
12
test.__name__ = test
------------------------
test1 with paras tuple () dic {'x': 3, 'y': 4} excute in 0.0 ms
12
test1.__name__ = test1
'''