有时候撸代码撸累了,想发发微信,找个人帮忙撸代码。你可以试试这样:@xxx 帮我打个日志。XXX就帮你打日志了。
def log(func):
def wrap(*arg, **kargs):
start = time.time()
func(*arg, **kargs)
end = time.time()
print " time = %.6f sec" % (end - start)
return wrap
然后你想要打日志,又懒得撸代码了,就这样:
@log
def foo(arg):
# do something
以下是干货,容易着火。
修饰器的本质就是对函数做些修饰,然后返回一个函数(callable object)。也就是所谓的高阶函数。
因此上面的式子不用语法糖直白的写出来就是:
foo = log(foo)
看到没,foo其实就是一个log返回的callable object wrap的别名。
举个栗子,如果需要这样的修饰器,我们应该怎么写呢?
@decro(1, 2)
def foo(args, *kargs):
pass
先翻译一下,先把(1,2)传给decro,然后把foo传给decro;然后你返回给我一个能接受(args,*kargs)参数的函数:
foo = decro(1,2)(foo)
一定要记住,foo是一个callable object。事情就变得很简单了:
def decro(args, *kargs): # 1,2
def wrap(func): # foo
def _(*args, **kargs): # foo 也必须是一个callable
func(*args, **kargs)
return _
return wrap
哪里不会点哪里,就是这么简单。装逼技能Decorator GET!
2) wraps
到这里就结束了?如果到这里就结束了,高年级的同学知道了一定又会回来鄙视我们:你试试打印下foo函数,看看是什么?你试着打印一下:
foo
天啦噜!不是foo么,怎么变成"_"了?
别急,这个时候你需要前一节提到的那条裤了:functools,然后对你的decorator做一点小小的改动:
from functools import wraps
def decro(args, *kargs):
def wrap(func):
# 看这里看这里
@wraps(func)
def _(*args, **kargs):
func(*args, **kargs)
return _
return wrap
然后foo就变成了:
foo