使用装饰器就是在现有函数的功能上套上额外的功能。一个简单的形式:
def deco(func):
return func
@deco
def func():
pass
这里deco就是func函数的装饰器。功能就是先把func()拿过来,作为deco函数的参数传进去后返回一个可用装饰器再把装饰器赋值给func(),等价于:func = deco(func)。
有个例子:
def log(func):
def wrapped():
print"%s() is called by log"%func.__name__ #该用法在py3.x中会报类型错误
return func() #注意这里有(),有括号指返回函数执行的结果
return wrapped #这里没(),指只返回该函数
@log
def func():
print"self at func()"
func()
执行结果为:
func() is called by log
self at func()
可以看出,装饰器本身就是一个含参函数,它只不过是用@+这个函数名声明成了一个装饰器函数放在需要被装饰的函数头上,这样下面的函数就会作为参数传入装饰器函数中,然后又经过在wrapped子函数(它才是真正的装饰器)中添加功能,再把这个参数(被装饰函数)的执行结果返回,接着装饰器函数返回wrapped子函数即装饰器,最后赋值给被装饰的函数,这样,被装饰的函数就有了额外的功能。
也就是在func()上加上log(),这样执行func()的时候就会先执行log()里面的函数再执行log中return的函数func()。return的可以不是func(),也可以是已经定义好的other函数,这样的话执行完log后接着执行的是other函数。
比如:
def deco(func):
print "this is deco"
return other
def other():
print "this is other"
@deco
def func():
print "this is func"
func()
执行结果为:
this is deco
this is other
完全把func的功能装饰掉了。
装饰器默认的参数就是被装饰的函数本身,相当于类中的self。
对于带有其他应用参数的,装饰器函数在调用时只会使用应用时的参数,而不接收默认的被装饰函数作参数。所以就必须要在外面在套一层接收参数的函数,在挨个返回。比如:
def test(a, b):
def log(func):
def wrapped():
print("a =%d, b =%d----- called by log")%(a, b)
return func()
return wrapped
return log
@test(1,2)
def func():
print("self at func()")
func()
执行结果为:
a = 1, b = 2 ----- called by log
self at func()
等价于:func = test(1, 2)(func)