装饰你的梦
一、不用装饰器
为函数增加计时
def deco(func):
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
def myfunc():
time.sleep(0.6)
deco(myfunc)
二、封装一层
def deco(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return wrapper
def myfunc():
time.sleep(0.6)
myfunc = deco(myfunc)
myfunc()
三、装饰器语法糖
def deco(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print(end_time - start_time)
return wrapper
@deco
def myfunc():
time.sleep(0.6)
myfunc()
使用了”@”语法糖后,我们就不需要额外代码来给”myfunc”重新赋值了,其实”@deco”的本质就是”myfunc=deco(myfunc)”,当认清了这一点后,后面看带参数的装饰器就简单了。
四、被装饰的函数带参数
def deco(func):
def wrapper(a, b):
start_time = time.time()
func(a, b)
end_time = time.time()
print(end_time - start_time)
return wrapper
@deco
def myfunc(a, b):
print("a + b =", a+b)
time.sleep(0.6)
myfunc(10, 9)
五、被装饰的函数带参数
这里还有一个问题,如果多个函数拥有不同的参数形式,怎么共用同样的装饰器?在Python中,函数可以支持(*args, **kwargs)可变参数,所以装饰器可以通过可变参数形式来实现内嵌函数的签名。
def deco(func):
def wrapper(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs)
end_time = time.time()
print(end_time - start_time)
return wrapper
@deco
def myfunc(a, b):
print("a + b =", a+b)
time.sleep(0.6)
myfunc(10, 9)
使用位置和关键字参数可以兼容各种函数,装饰器就成了通用的了。
使用了*args位置参数和**kwargs关键字参数,不明白先补下知识点。
六、被装饰函数有返回值
def deco(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print(end_time - start_time)
return res
return wrapper
@deco
def myfunc(a, b):
time.sleep(0.6)
return a+b
res = myfunc(10, 9)
print(res)
七、装饰器也想带参数
功能:装饰器里的计时功能可以关闭
def deco(arg=True):
if arg:
def _deco(func):
def wrapper(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs)
end_time = time.time()
print(end_time - start_time)
return wrapper
else:
def _deco(func):
return func
return _deco
@deco(arg=False) # 这里注意下, @deco(arg=False)先执行,就变形成了@_deco(func)
def myfunc(a, b):
print("a + b =", a+b)
time.sleep(0.6)
myfunc(10, 9)
又封装一层,好多层!
八、多个装饰器
离函数近的优先执行
def deco_1(func):
def wrapper(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs)
end_time = time.time()
print(end_time - start_time)
return wrapper
def deco_2(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print("from deco_2:")
return wrapper
@deco_1
@deco_2
def myfunc(a, b):
print("a + b =", a+b)
time.sleep(0.6)
myfunc(10, 9)
参考:
http://www.cnblogs.com/linhaifeng/articles/7532497.html#_label5
http://python.jobbole.com/82344/