装饰器--装饰器的种类
没有装饰器实例:
1 #!/usr/bin/env python 2 # -*- coding:utf8 -*- 3 # Author:Dong Ye 4 5 6 #定义个全局变量,用于存放用户状态信息: 7 LOGIN_USER = {"is_login": False, "current_user": None} 8 9 10 #查看订单: 11 def order(): 12 if LOGIN_USER['is_login']: 13 print('欢迎%s登录' % LOGIN_USER['current_user']) 14 else: 15 print('请登录') 16 17 18 #修改密码: 19 def changepwd(): 20 if LOGIN_USER['is_login']: 21 print('欢迎%s登录' % LOGIN_USER['current_user']) 22 else: 23 print('请登录') 24 25 26 #后台管理: 27 def manager(): 28 if LOGIN_USER['is_login']: 29 print('欢迎%s登录' % LOGIN_USER['current_user']) 30 else: 31 print('请登录') 32 33 34 #登入 35 def login(user,pwd): 36 if user == 'alex' and pwd == '123': 37 LOGIN_USER['is_login'] = True #表示登录成功 38 LOGIN_USER['current_user'] = user #当前用户名称 39 manager() #登入成功后,就可以访问后台管理。 40 41 42 #用户输入判断: 43 def main(): 44 while True: 45 inp = input("1、后台管理;2、登录") 46 if inp =='1': 47 manager() 48 elif inp == '2': 49 username = input('请输入用户名:') 50 pwd = input('请输入密码:') 51 login(username,pwd) 52 53 54 #调用方法 55 main()
一级装饰器:(用户登录)
一个函数用一个装饰器装饰
实例1:
#!/usr/bin/env python # -*- coding:utf8 -*- # Author:Dong Ye #第一步,定义outer函数 def outer(func): #第五步、func = 原来的f1函数的内存地址 def inner(): print('hello') #第六步 print('hello') print('hello') #第七步、找到原来的f1并执行f1的函数体 #第八步、将原来f1的返回值赋值给r r = func() print('end') #第九步 print('end') print('end') print('end') return r #第十步、由于inner是被新f1的函数调用,返回原来f1的返回值,也会返回给新f1的ret变量 return inner #第二步、在python中@代码具有特殊性,只要解析器执行到@,就会有下面的2个操作: #1、执行outer函数,并且将其下面的函数名当做参数。 #2、将outer返回值重新赋值给f1 @outer def f1(): #第三步、f1接收outer的返回值变成inner的内存地址f1 = inner的内存地址 print('F1') ret = f1() #第四部、调用f1的时候,直接执行inner的函数体 #第十一步、由于inner是被新f1的函数调用,返回原来f1的返回值,也会返回给新f1的ret变量 print(ret)
实例2:
1 #定义个全局变量,用于存放用户状态信息: 2 LOGIN_USER = {"is_login": False, "current_user": None} 3 4 #装饰器: 5 def outer(func): 6 def inner(*argsm,**kwargs): 7 if LOGIN_USER['is_login']: 8 print('欢迎%s登录' % LOGIN_USER['current_user']) 9 r = func() 10 return r 11 else: 12 print('请登录') 13 return inner 14 15 16 17 18 #查看订单: 19 @outer 20 def order(): 21 print('欢迎%s登录' % LOGIN_USER['current_user']) 22 23 24 #修改密码: 25 @outer 26 def changepwd(): 27 print('欢迎%s登录' % LOGIN_USER['current_user']) 28 29 30 #后台管理: 31 @outer 32 def manager(): 33 print('欢迎%s登录' % LOGIN_USER['current_user']) 34 35 36 #登入 37 def login(user,pwd): 38 if user == 'alex' and pwd == '123': 39 LOGIN_USER['is_login'] = True #表示登录成功 40 LOGIN_USER['current_user'] = user #当前用户名称 41 manager() #登入成功后,就可以访问后台管理。 42 43 44 #用户输入判断: 45 def main(): 46 while True: 47 inp = input("1、后台管理;2、登录") 48 if inp =='1': 49 manager() 50 elif inp == '2': 51 username = input('请输入用户名:') 52 pwd = input('请输入密码:') 53 login(username,pwd) 54 55 56 #调用方法 57 main()
二级装饰器:(用户登录和权限认证)
注意:一个函数可以你被多个装饰器装饰
#!/usr/bin/env python # -*- coding:utf8 -*- # Author:Dong Ye #定义全局字典: USER_INFO = {} #判读用户登录: def check_login(func): def inner(*args,**kwargs): if USER_INFO.get('is_login',None): #如果获取不到返回None ret =func(*args,**kwargs) return ret else: print('请先登录。。。') return inner #判读用户管理: def check_admin(func): def inner(*args,**kwargs): if USER_INFO.get('user_type',None)==2: ret =func(*args,**kwargs) return ret else: print('无权限查看。。。') return inner @check_login @check_admin def index(): ''' 管理员登录 :return: ''' print('index') @check_login def home(): print('home') def login(): user = input('请输入用户名:') if user == 'admin': #如果用户登录属于管理员。 USER_INFO['is_login'] = True #登录状态为True USER_INFO['user_type'] = 2 #用户类型为2(管理员)。 else: USER_INFO['is_login'] = True USER_INFO['user_type'] = 1 #用户类型为1(普通用户)。 def main(): while True: inp = input('1、登录;2、查看信息;3、超级管理员 \n >>>') if inp == '1': login() elif inp =='2': home() elif inp == '3': index() main()
超级装饰器
实例1:
1 #!/usr/bin/env python 2 # -*- coding:utf8 -*- 3 # Author:Dong Ye 4 5 6 import time 7 user,passwd = 'dy','asd' 8 #装饰器 9 def auth(auth_type): #定义一个装饰器标签函数,auth_type是装饰器的标签(auth_type = "local" & auth_type="ldap") 10 print("auth func:",auth_type) 11 def outer_wrapper(func): #定义接收@auth传过来的home的内存地址,并赋值给func 12 def wrapper(*args,**kwargs): #定义嵌套函数,做功能装饰home() & bbs(),并且home(args1) & bbs(args1)的参数会传到这里 13 #print("wrapper func args:",*args,**kwargs) 14 if auth_type == 'local': 15 username = input('username: ').strip() 16 password = input('password: ').strip() 17 if user == username and passwd == password: 18 print("\033[32;1mUser has passed authentication\033[0m") 19 return func(*args,**kwargs) #执行源代码home() & bbs(),并且home(args1) & bbs(args1)的参数会传到这里 20 else: 21 exit("\033[31;1mInvalid username or password\033[0m") 22 23 elif auth_type=='ldap': 24 print('是以ldap的方式登录') 25 return wrapper 26 return outer_wrapper 27 28 #注释: 29 #home----传参:内存地址和装饰器标签(local&ldap)----> auth(解封装),auth_type=装饰器标签 -----home的内存参数---->outer_warpper(解封装),func= home---->调用wrapper(*args,**kwargs)-->func函数func(*args,**kwargs)=home(*args,**kwargs) 30 #wrapper ----内存地址1---->outer_wrapper----内存地址1和2---->auth--内存地址(1、2)通过装饰器标签(local&ldap)---->home重新赋值 31 def index(): 32 print('welcome to index page') 33 34 #原代码 35 #home认证用本地认证 36 #auth_type = "local" 赋值给了auth(auth_type) 37 #@auth home = auth(outer_wrapper(func)) func = home 38 #通过高阶函数的功能将wrapper的内存地址返回给outer_wrapper 39 #最后将outer_wrapper的内存地址返回给auth函数,并重新赋值给home 40 @auth(auth_type = "local") 41 def home(): 42 print('welcome to home page') 43 return "from home" 44 45 注意:调用2次,赋值一次:第一次auth_type调用auth(auth_type);第二次@auth调用outer_wrapper(func);第三次将home函数赋值给wrapper(*args,**kwargs) 46 47 48 49 #bbs用远程的ldap 50 @auth(auth_type="ldap") #bbs = auth(bbs) 51 def bbs(): 52 print('welcome to bbs page') 53 54 55 56 57 58 #原调用 59 index() 60 home() #其实执行的是通过wraooer、outer_warpper、auth返回的内存地址,找到wrapper函数体执行的 61 bbs()
实例2:
1 def Before(request,kargs): 2 print 'before' 3 4 def After(request,kargs): 5 print 'after' 6 7 8 def Filter(before_func,after_func): 9 def outer(main_func): 10 def wrapper(request,kargs): 11 12 before_result = before_func(request,kargs) 13 if(before_result != None): 14 return before_result; 15 16 main_result = main_func(request,kargs) 17 if(main_result != None): 18 return main_result; 19 20 after_result = after_func(request,kargs) 21 if(after_result != None): 22 return after_result; 23 24 return wrapper 25 return outer 26 27 @Filter(Before, After) 28 def Index(request,kargs): 29 print 'index'