装饰器是Python的一个特性,其实就是对callable对象的一个包装。下面是几个例子:

1.修饰器自身不带有参数,那么AAA的参数就是func

1
2
3
4
5
6
7
8
9
def AAA(f):
    def wrapper(YYY):
        XXX
        f(YYY)
    return wrapper
 
@AAA
def func(OOO):
    XXX

等价于(默认会执行下面一步,也就是哪怕没有运行的代码,初始化模块的时候也会执行下面代码)

1
func = AAA(func)  #func以参数f的形式被AAA调用,同时返回一个callable的对象。

2.如果修饰器自身带有参数,那么AAA的参数就不是func,func会的被传递到AAA生成的wrapper中,如:

1
2
3
4
5
6
7
8
9
10
11
12
def AAA(fff):
    print fff
    def wrapper(f):
        def _wrapper(OOO):
            print "_wrapper"
            f(OOO)
        return _wrapper
    return wrapper
 
@AAA('bbb')
def func(OOO):
    print OOO

等价于(其会执行下面一步,也就是哪怕没有运行的代码,初始化模块的时候也会执行下面代码。换句话说AAA(‘bbb’)这个不管你func有没有 被调用都会的执行,而func实际上等价于wrapper(func),wrapper(func)会的返回_wrapper,因此调用 func(XXX)就变成了调用_wrapper(XXX)):

1
func = AAA('bbb')(func)

也就是说,有没有参数对于修饰器来说传递func的时机是不同的,这点务必注意。这点理解过后,func的具体内容就可以自己通过g(f(x))这种来推导了。同时记住,推导的那些代码在模块初始化的时候是铁定会执行的,不管你实际上有没有代码。

3.如果是作用在class上,那么等价于作用在__init__上,如:

1
2
3
4
5
6
7
8
9
10
11
12
def AAA(f):
    def wrapper():
        print "AAA"
        f()
    return wrapper
 
@AAA
class C():
    def __init__(self):
        print "INIT"
 
c = C()

输出是:

1
2
AAA
INIT
 posted on 2015-01-07 17:12  zmlctt  阅读(284)  评论(0编辑  收藏  举报