py学习笔记05 装饰器
递归拾遗
"""
利用函数编写如下数列:
斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,
377,610,987,1597,2584,4181,6765,10946,17711,28657,46368
前两数相加既得后一个数字
"""
def func(arg1,arg2):
if arg1 == 0:
print arg1, arg2
arg3 = arg1 + arg2
print arg3
if arg3 > 1000:
return arg3
func(arg2, arg3)
func(0,1)
def func1(arg1,arg2):
if arg1 == 0:
pass
arg3 = arg1 + arg2
if arg3 > 1000:
return arg3
ret = func1(arg2,arg3)
return ret
result = func1(0,1)
print result
装饰器
装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作。
学前班:
#### 第一波 #### def foo(): print 'foo' foo #表示是函数 foo() #表示执行foo函数 #### 第二波 #### def foo(): print 'foo' foo = lambda x: x + 1 foo() # 执行下面的lambda表达式,而不再是原来的foo函数,因为函数 foo 被重新定义了
装饰器使用场景:
假设公司有N个业务部门,1个基础平台部门,基础平台负责提供底层的功能,如:数据库操作、redis调用、监控API等功能。业务部门使用基础功能时,只需调用基础平台提供的功能即可,示例如下:
############### 基础平台提供的功能如下 ############### def f1(): print 'f1' def f2(): print 'f2' def f3(): print 'f3' def f4(): print 'f4' ############### 业务部门A 调用基础平台提供的功能 ############### f1() f2() f3() f4() ############### 业务部门B 调用基础平台提供的功能 ############### f1() f2() f3() f4()
先来查看一个最简单的装饰器代码:
#无参数的装饰器 def auth(func): #func = f1 =====>func() <===>f1() def inner(): print 'before' #验证的内容 func() #f1 ====> 原函数 print 'after' #验证成功后执行的操作 return inner @auth #等同于f1 = auth(f1) def f1(): print 'f1'
业务调用方法:
#装饰器执行函数 import basic basic.f1() 执行结果为: before f1 after
这种装饰器的使用还是具有局限性,如果我们想要传参,应该怎么办。。。。看下面
可以传入参数的装饰器:
#有参数的装饰器 def auth_arg(func): #func = f1 =====>func() <===>f1() def inner(arg): print 'before' func(arg) #f1 ====> 原函数 print 'after' return inner #多参数的装饰器,内层函数设置成动态参数 def auth_args(func): #func = f1 =====>func() <===>f1() def inner(*arg,**kwargs): print 'before' func(*arg,**kwargs) #f1 ====> 原函数 print 'after' return inner @auth_args def f2(arg1,arg2): print 'f2',arg1,arg2 @auth_args def f5(arg): print 'f5',arg
此种方式业务的调用方式如下:
import basic #有参数的装饰器 basic.f5('123')
basic.f6('1','2')
输出结果为: before f5 123 after
before
f6 1 2
after
可以看到已经把我们传入的参数输出了出来
装饰器小小节:
1.装饰器是一个函数 2. 执行auth_args函数,被装饰的函数作为参数auth_args(f1) auth_args 函数的返回值, 赋值给被装饰的函数的函数名 @auth_args def f1(): pass 3.动态参数,可以装饰含有n个参数的函数 4.函数返回值 5.多装饰器 6.至少3层,3层的如何使用? @auth_args 1.执行auth_args函数 2.将auth_args函数的返回值给赋值给被装饰器的函数的函数名 @auth_args(arg) 1.执行auth_args函数,得到返回值,result 2.创建装饰器,@ + result结合:@result 3... 1).执行result 函数 2).将result函数的返回值给被装饰器的函数的函数名
功能看似完美了,但是如果我需要返回值,怎么整。。。。。
一样可以解决,看下:
#可接收返回值得装饰器 def auth_return(func): #func = f1 =====>func() <===>f1() def inner(*arg,**kwargs): print 'before' temp = func(*arg,**kwargs) #f1 ====> 原函数 print 'after' return temp return inner @auth_return def fetch_host_list(arg): server_list = ['c1','c2','c3'] return server_list
业务调用如下:
import basic #可接受返回值的装饰器 reg_list = basic.fetch_host_list('test') print reg_list 输出结果: before after ['c1', 'c2', 'c3']
猪脚要来了。我们做个用户登录验证的操作吧^_^
看下面:
#用户验证装饰器 def login(): name = 'ares' if name == 'ares': return True else: return False def auth_login(func): #func = f1 =====>func() <===>f1() def inner(*arg,**kwargs): if not login(): return "非法请求" temp = func(*arg,**kwargs) #f1 ====> 原函数 print 'after' return temp return inner @auth_login def f7login(arg): server_list = ['c1','c2','c3'] return server_list
业务调用方法:
import basic #判断用户登录装饰器 ser_list = basic.f7login('test') print ser_list 输出结果: after ['c1', 'c2', 'c3'] #若login函数里传入用户名不为ares,则在此处会输出‘非法请求’
功能看似强大,但是不是很灵活,不如加个key值判断方便:
#使用key验证 def login1(key): local = "1231" if local == key: return True else: return False def auth_login1(func): #func = f1 =====>func() <===>f1() def inner(*arg,**kwargs): key = kwargs['token'] del kwargs["token"] #key = kwargs.pop('token') #这一句等于 上面注释的两句 #这句含义:因为下面的login 只接受一个参数,这里多一个参数,所有删除 is_login = login1(key) if not is_login: return "非法用户" temp = func(*arg,**kwargs) #f1 ====> 原函数 print 'after' return temp return inner @auth_login1 def f8login(arg): server_list = ['c1','c2','c3'] return server_list
业务调用方式:
import basic #使用key验证 key = "123" #与函数的key不一致 ser_list1 = basic.f8login('test',token=key) print ser_list1 key = "1231" #与函数的key一致 ser_list1 = basic.f8login('test',token=key) print ser_list1
输出结果分别为:
非法用户 #key不一致的情况 after #key一致的情况 ['c1', 'c2', 'c3']
什么,单装饰器还不牛,别急,还有多装饰器!!!
双装饰器示例:
@auth_login @auth_login def f1(): pass 执行的结果: 就是一层套一层
双装饰用途:
双层装饰器,可以用在以下途径:
比如用户权限管理,第一层装饰器用于用户名密码验证,
第二层用在 判断用户是什么身份的用户,比如:普通用户,超级用户等
还有一个更屌的装饰器:
#!/usr/bin/env python #coding:utf-8 def Before(request,kargs): print 'before' def After(request,kargs): print 'after' def Filter(before_func,after_func): 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) def Index(request,kargs): print 'index'

浙公网安备 33010602011771号