import functools
def a(f):
print('a')
@functools.wraps(f)
def wraps(*args, **kwargs):
print('wraps')
return f(*args, **kwargs)
return wraps
@a
def b():
print('b')
b()
b()
第二次调用b()函数,并没有输出’a’,其实调用b(),b()相当于
import functools
def a(f):
print('a')
@functools.wraps(f)
def wraps(*args, **kwargs):
print('wraps')
return f(*args, **kwargs)
return wraps
def b():
print('b')
b = a(b) //此时打印'a'
b()
b()
# 当导入b的时候装饰器已经运行,而不是自己原以为的调用b时装饰器才运行
In [1]: from t1 import b
a
update_wrapper是wraps的主要功能提供者,它负责考贝原函数的属性,默认是:’module‘, ‘name‘, ‘doc‘, ‘dict‘
functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
# 通过wraps和update_wrapper实现结果是一致的
In [28]: from functools import wraps, update_wrapper
In [29]: def time1(func):
...: @wraps(func)
...: def wrapper(*args, **kwargs):
...: start = time.time()
...: func(*args, **kwargs)
...: end = time.time()
...: print(func.__name__, end-start)
...: return wrapper
...:
In [30]: def time2(func):
...:
...: def wrapper(*args, **kwargs):
...: start = time.time()
...: func(*args, **kwargs)
...: end = time.time()
...: print(func.__name__, end-start)
...: return update_wrapper(wrapper,func)
...:
...:
In [31]: @time1
...: def fori():
...: for i in range(1000):
...: pass
...:
In [32]: fori()