[Python] 函数 @ Decorator 的两种使用方式

python中的@标签看上去有点类似于Java里的@ annotation。其主要功能是用@标签后面的函数(A)对 @标签下面的函数(B)进行一些加工。

它虽然不是非用不可,但能提高代码的可读性,降低耦合度。

方式一:

@A
def f():  
    pass

大致等同于 f = A(f)

例子一:

def check(f):  
    print 'start run check()'
    def new_f():
        print 'hello from new_f'
        f()
    return new_f

@check
def func():  
    print 'hello from func'

func()  
func()  

执行结果:

start run check()  
hello from new_f  
hello from func  
hello from new_f  
hello from func  

这个例子很多说明问题,在@check绑定的时候,func() = check(func) = newf(),随后每次执行func()实际上调的newf(),而在new_f()里面调用原来的func函数。

例子二 (实际应用):

#login_check对add_entry函数进行预处理,如果用户已经登陆过才执行真正的add_entry函数。
def login_check(f):  
    def new_f():   
        if not session.get('username'):
            app.logger.debug("not login, redirct to login page ")
            return redirect(url_for('login'))
        else:
            '''
        not f() here, otherwise, equal to "redirect(redirect_url())" in this line,
        but not "return redirect(redirect_url())", which is supposed to be
            '''
            return f()
    return new_f
@login_check
def add_entry():  
     do something

方式二:

@A(a, b, c)

def f():  
    pass

大致等同于  f= A(a, b, c) (f)

也就是:

def f():  
    pass
decorator = A(a, b, c)  
f = decorator(f)  

所以,在A函数中,要产生并返回一个所需的decorator函数。

参考:http://python.org/dev/peps/pep-0318/#why  

admin

0