定义
装饰器又称之为语法糖。它是在不改变原函数的的情况下为原函数添加一些额外的功能。
它有以下两个特征:
- 一个函数可以接受一个参数(接收的是正在装饰的函数为参数)
- 将结果返回给原函数
def mydecorator():
pass
@mydecorator
def myfunc():
pass
等同于
def mydecorator():
pass
def myfunc():
pass
myfunc = mydecorator(myfunc)
下面有很简单的例子:
不使用装饰器语法
def mydec(a_func):
def wrapper():
print "---------------------------"
print "Before the function runs"
a_func()
print "After the function runs"
print "---------------------------"
return wrapper
def a_new_func():
print "I am a doubi function"
a_new_func() #1
a_new_func = mydec(a_new_func)
a_new_func() #2
#outputs:
#I am a doubi function #1
#--------------------------- #2
#Before the function runs
#I am a doubi function
#After the function runs
#---------------------------
使用装饰器语法:
@mydec
def a_another_func():
print "I am not a doubi function"
a_another_func()
#outputs:
#---------------------------
#Before the function runs
#I am not a doubi function
#After the function runs
#---------------------------
装饰器还可以进行累加操作:
#bold decorator
def makebold(fn):
def wrapper():
return "<b>" + fn() + "</b>"
return wrapper
#italic decorator
def makeitalic(fn):
def wrapper():
return "<i>" + fn() + "</i>"
return wrapper
def say():
return "hello world"
say = makebold(makeitalic(say)) #1
print say()
#outputs
#<b><i>hello world</i></b>
say = makeitalic(makebold(say)) #2
print say()
#outputs
#<i><b>hello world</b></i>
此方法等价于:
@makebold
@makeitalic
def say():
return "hello world"
#outputs
#<b><i>hello world</i></b>
@makeitalic
@makebold
def say():
return "hello world"
#outputs
#<i><b>hello world</b></i>
由上面的例子可以发现,装饰器的顺序是很重要的。
装饰器的高级用法
装饰器的参数传递
#coding=utf-8
#通过包装函数来传递参数
def mydec(func):
def wrapper(arg1,arg2):
print "I got args! Look: ",arg1,"and",arg2
func(arg1,arg2)
return wrapper
#当你调用装饰器返回的函数,实际上是调用包装函数,所以给包装函数传递参数即可将参数传给装饰器函数
@mydec
def new_func(name1,name2):
print "My friends name is: ",name1,"and",name2
new_func("Han mei mei","Lilei")
#outputs:
#I got args! Look: Han mei mei and Lilei
#My friends name is: Han mei mei and Lilei