Python的修饰器的英文名叫Decorator。‘@’修饰符必须出现在函数定义前一行,不允许和函数定义在同一行。也就是说@A def f(): 是非法的。 只可以在模块或类定义层内对函数进行修饰,不允许修饰一个类。
所谓装饰器就是把原函数包装一下,对原函数进行加工,添加一些附加功能,装饰器本身就是一个函数,就是将被装饰的函数当作参数传递给装饰器,返回包装后的函数:你可以试下:
def d(fp): def _d(*arg, **karg): print "do sth before fp.." r= fp(*arg, **karg) print "do sth after fp.." return r return _d @d def f(): print "call f" #上面使用@d来表示装饰器和下面是一个意思 #f = d(f) f()#调用f
装饰器带参数:再包装一层被装饰的函数还有其他参数:上面的例子包装函数就是接收任意形式的参数
其实带参数的装饰器是经过调用”装饰器”函数返回的一个装饰器, 之所以装饰器上打引号是说明这个所谓的”装饰器”只不过是一个普通的函数, 但这个普通的函数返回一个装饰器。
一个修饰符就是一个函数,它将被修饰的函数做为参数传入,并返回修饰后的函数或其它可调用的东西。
先看一段代码
#!/usr/bin/python def test(func): func() @test def fun(): print "call fun"
上面的代码没有main()调用或者直接的函数调用,结果还是会输出
call fun
@修饰符有点像函数指针,python解释器发现执行的时候如果碰到@修饰的函数,首先就解析它,找到它对应的函数进行调用,并且会把@修饰下面一行的函数作为一个函数指针传入它对应的函数。有点绕口,这里说的“它对应的函数”就是名字是一样的。下面说下之前代码的解析流程:
1.python解释器发现@test,就去调用test函数
2.test函数调用预先要指定一个参数,传入的就是@test下面修饰的函数,也就是fun()
3.test()函数执行,调用fun(),fun()打印“call fun”
再看一段代码
#!/usr/bin/python def test(func): func() print "call test over" def main(): @test def fun(): print "call fun" #main()
这样调用的话就不会调用test,只有当main函数调用的时候才会进入到main函数,然后调用test
其他资料参考
Python修饰器的函数式编程
http://www.open-open.com/lib/view/open1395285030019.html
Python进阶
http://www.wklken.me/category/pythonru-men-ji-jin-jie-bi-ji.html
Python装饰器学习(九步入门)
http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html
Python深入05 装饰器
http://www.cnblogs.com/vamei/archive/2013/02/16/2820212.html