Tempest里用例的测试都会用到装饰器,虽然声称很方便,但我看来还是感觉比较非主流
#!/usr/bin/env python # coding: utf-8 def decorator(func): def subfun(): print 'subfun()' return func return subfun @decorator def foo(): print 'foo()' foo()
经常会看到函数的定义前面加了一个@XXXX的玩意,顿时感觉python也有perl里乱七八糟的符号?上面这段初步一看,不知道他想表达什么,那么接着看下面这段
#!/usr/bin/env python # coding: utf-8 def decorator(func): def subfun(): print 'subfun()' return func return subfun def foo(): print 'foo()' foo = decorator(foo) foo()
这段就比较直接了,foo作为参数传到了decorator里,返回的其实是一个函数对象,然后被=左边的foo指,但是注意的是=左边的变量foo只是一个同名的玩意,原来的函数foo依旧存在,而这个新同名的foo指向的是decorator返回的新函数,所以最终调用foo()会执行decorator里的subfun函数,打印subfun()这一行信息,而不会打印foo()
如果对于这点表示怀疑,最后两行随便改下试试
myfoo = decorator(foo) myfoo()
所以根据这个过程,再来看第一段,在foo的定义前面加了一行@decorator,就说明decorator是一个装饰器,以函数为参数,并返回一个函数,自身其实也是一个函数,具体放到哪个函数前面,就把哪个函数当做参数传
说得更直接一点,最终的函数调用,实际上执行的都是装饰器内嵌的函数,装饰器只负责传函数和返回函数
随便看了tempest里的几个测试用例,基本装饰器里到带了参数,比如下面
#!/usr/bin/env python # coding: utf-8 def decorator(when): def subfun(func): def fun(): print '%s, %s' %(when, func.__name__) return fun return subfun @decorator('Now') def foo(): print 'foo()' foo()
执行顺序是,首先decorator(‘Now’),会调用sub fun,然后将foo作为参数传进去执行,接着调用fun,最终打印出信息:Now,foo
也就是说,这里装饰器的含义为foo = decorator(‘Now’)(foo)
总之,装饰器在我看来就是函数嵌套,理清调用顺序和返回即可,其它更多复杂情况可慢慢理或者搜索一把