装饰器
程序员文章站
2022-03-16 11:12:33
...
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
执行过程如下:
含一个参数的装饰器
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) 执行过程:
主要参考链接:
转载于:https://blog.51cto.com/ttxsgoto/1773753