Python函数装饰器

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)

总之,装饰器在我看来就是函数嵌套,理清调用顺序和返回即可,其它更多复杂情况可慢慢理或者搜索一把


 

发表回复