python装饰器
今天看了装饰器的一些内容,感觉@修饰符还是挺抽象的。
装饰器就是在不用改变函数实现的情况下,附加的实现一些功能,比如打印日志信息等。需要主意的是装饰器本质是一个高阶函数,她可以返回一个函数。
装饰器需要用到@修饰符,我们举一个例子:
这个返回函数的函数是一个装饰器
然后我们定义需要被它装饰的函数,是这样的:
然后我们调用函数gril()便会打印如下内容:
那么这一过程如何实现呢,现在我不知道,我来研究。
首先查一下官方doc
========================= 中朝边境线 =========================
其实这个文档说的已经很清楚很好了。大概翻译一下:
一个函数定义可以被一个或者几个装饰器表达式包含(wrapped,此词用的尤为好,就是我们那个gril函数被boy函数包含了,这其实更有助于理解装饰器了)。在含有函数定义的区域内,当函数被定义时,装饰器是被评估的??(这里翻译不了,英语渣渣)。装饰器的返回结果是必须要能被调用的(也就是返回值是一个函数),他作为一个参数被这个函数对象调用。装饰器的返回值被和原来的那个函数的名字绑定来取代原来的函数对象。在嵌套样式里应用多个装饰器(抱歉,我也不知道我说了什么)。
我们看到他给的第一个例子等同于第一个例子,如果对应于我们上边举的例子那就是:
@boy def gril(): print 'I am gril.'
就等同于
gril = boy(gril)
注意此时的gril已经变成了boy函数。验证一下
那么现在f2应该变成了f1(f2)
如果调用f2应该是两句都会打印,试一下
果真是。。-> _ ->
那么装饰器是怎么回事呢?
其实我们可以看到调用gril函数其实变成了调用boy函数的返回值也就是money函数,money函数先是打印了一句信息,然后它会返回原先gril函数的调用--原先的gril函数被执行了(原先gril函数已经在@修饰符下被当作参数传给boy函数了),所以它在打印完信息后返回原先gril的调用。
*args,**kw这两个参数是表示可以接收任意个数的参数的,这样不论原先gril函数有怎么样的形参,新的gril函数(也就是money)总是能够被正确的调用!!
这样就基本清楚了,注意我上边翻译官方文档提到的warp这个词,这个词是‘包含’的意思,也就是现在的gril已经变成了包含执行原先gril函数的money函数,这样不仅原先gril函数能被执行,而且money函数还可以自己添加一些功能被顺带的执行了。所以说啊,文档中这个warp用的很贴切,很温馨,犹如午后的阳光洒在单纯而广袤的程序猿们的心田,暖暖的。