python装饰器,个人感觉还是不怎么好理解,这两天又学习了一篇,记录一下相关知识点;


主要功能
给程序去重,在不改动源代码和原有调用方式下,给函数添加额外的功能模块(如验证功能)


装饰器理解
装饰器就是执行一个函数,当执行到@auth时,内部的动作为:
1.执行auth函数,并将@auth下面的函数作为auth函数的参数,即@auth == auth(f1)
2.将执行完的auth函数返回值赋给@auth下面的函数的函数名

  • 最简单的例子(无参数)

def auth(func):
    def inner():
        print "before"    #执行函数前执行动作
        func()
        print "after"    #执行函数后执行动作
    return inner
    
@auth  #@auth ==> f1 = auth(f1) ==>f1() 相当于执行inner函数,func为f1函数
def f1():
    print "f1"

f1()
运行结果:
before
f1
after

执行过程如下:

wKiom1c4lR3QxLoVAADfYaEBuKw373.png

  • 含一个参数的装饰器

def auth_arg(func):
    def inner(arg): #传递一个参数
        print "before"
        func(arg)    #相当于f2(arg)函数
        print "after"
    return inner

@auth_arg
def f2(arg):
    print 'f2',arg

f2('ttxsgoto')
运行结果:
before
f2 ttxsgoto
after
  • 含多个参数的装饰器(重要),都可以使用这个装饰器,包括一个,两个,多个参数

def auth_args(func):
    def inner(*args,**kwargs): #接收多个参数时
        print "before"
        func(*args,**kwargs)
        print "after"
    return inner

@auth_args
def f3(arg1,arg2):
    print "f3:", arg1,arg2

f3('ttxs','goto')
运行结果:
before
f3: ttxs goto
after
  • 有返回值的装饰器

def auth_arg_return(func):
    def inner(*args,**kwargs): #接收多个参数时
        print "before"
        ret = func(*args,**kwargs) #通过ret来接收func函数的返回值
        print "after"
        return ret  #返回func函数的返回值
    return inner

@auth_arg_return
def f4(arg):
    print "f4"
    list1=[1,2,3]
    return list1

temp = f4('abc')
print temp
运行结果:
before
f4
after
[1, 2, 3]
  • 装饰器登录验证原理

def login():
    name = "ttxsgoto"
    if name == "ttxsgoto":
        return True
    else:
        return False

def auth(func):
    def inner(*args,**kwargs):
        is_login = login() #执行login函数
        if not is_login:
            return "非法请求"
        ret = func(*args,**kwargs)
        return ret
    return inner

@auth    #需进行验证后,在执行功能函数
def get_list(arg):
    list1 =['a','b','c']
    return list1

temp1 = get_list("ttxs")
print temp1
执行结果:
['a', 'b', 'c']
  • 多装饰器

        - 在foo函数上层包裹了一层w1,又包裹了一次w2,一个嵌套一个函数,执行
        - 可用于登录后再判断有没有权限,可以使用两个装饰器

def w1(func):
    def inner():
        print "before01"
        func()
        print "after01"
    return inner

def w2(func):
    def inner():
        print "before02"
        func()
        print "after02"
    return inner

@w2
@w1
def foo():
    print "foo"

foo() #先执行w2,在执行w1,嵌套执行
运行结果:
before02
before01
foo
after01
after02
  • 有参数的装饰器@auth(arg1,arg2)

        执行分三步操作:
            1.先执行auth(arg1,arg2)函数,返回值为ret
            2.获取返回值ret,拼接成@ret装饰器
            3.执行ret对应的装饰器,同上面普通的装饰器执行过程
            4.最终@ret装饰器可以使用arg1,arg2,以及@ret里面的参数,主要目的就是使用auth定义的参数

def Before(request,kargs):
    print "before"

def After(request,kargs):
    print "after"

def Filter(before_func,after_func): #在普通装饰器上层在封装了一个函数,作用传递before_func,after_func两个变量给outer使用
    def outer(main_func): #普通装饰器
        def wrapper(request,kargs):
            before_result=before_func(request,kargs)
            if (before_result != None):
                return before_result
            main_result = main_func(request,kargs)
            if (main_result != None):
                return main_result
            after_result = after_func(request,kargs)
            if (after_result != None):
                return after_result
            return wrapper
    return outer

@Filter(Before, After) #==> 返回outer函数 ==>等价于 @outer ==>执行普通的装饰器
def Index(request,kargs):
    print "index"

有参数的装饰器@auth(arg1,arg2) 执行过程:

wKioL1c4l3KBtWyXAACCCPRky0M564.png


主要参考链接:

http://www.cnblogs.com/wupeiqi/articles/4980620.html