什么是装饰器?
装饰器(Decorator)相对简单,咱们先介绍它:“装饰器的功能是将被装饰的函数当作参数传递给与装饰器对应的函数(名称相同的函数),并返回包装后的被装饰的函数”,听起来有点绕,没关系,直接看示意图,其中 a 为与装饰器 @a 对应的函数, b 为装饰器修饰的函数,装饰器@a的作用是:
简而言之:@a 就是将 b 传递给 a(),并返回新的 b = a(b)
闭包与装饰器
上面已经简单演示了装饰器的功能,事实上,装饰器就是一种的闭包的应用,只不过其传递的是函数:
In [93]: def hello():
...: return "hello world!"
...:
In [94]: hello()
Out[94]: 'hello world!'
In [90]: def makeitalic(fn):
...: def wrapped():
...: return ("<i>"+fn()+"</i>")
...: return wrapped
...:
...:
In [84]: def makebold(fn):
...: def wrapped():
...: return ("<b>"+fn()+"</b>")
...: return wrapped
In [85]: @makebold
...: def hello():
...: return "hello world!"
...:
In [86]: hello()
Out[86]: '<b>hello world!</b>'
In [88]: @makeitalic
...: @makebold
...: def hello():
...: return "hello world!"
...:
In [92]: hello()
Out[92]: '<i><b>hello world!</b></i>'
@makeitalic 装饰器
将函数 hello
传递给函数 makeitalic
,函数 makeitalic
执行完毕后返回被包装后的 hello 函数
,而这个过程其实就是通过闭包实现的。@makebold
也是如此,只不过其传递的是 @makeitalic
装饰过的 hello 函数
,因此最后的执行结果<b>
在<i>
外层.
这个功能如果不用装饰器,其实就是显式的使用闭包: