一、什么是装饰器
l=[1,3] l.__iter__() ==》 iter(l) 迭代器
装饰器:本质就是函数,修饰其他函数,功能是为其他函数添加附加功能
两个原则:
1. 不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器的知识储备
装饰器=高阶函数+函数嵌套+闭包
高阶函数定义
1.函数接受的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
闭包
函数内部定义函数,一个包裹一个包裹的层级,
grandson是最里层的包 第二层 包裹是son 最后一层包裹是father
三个包一个套一层
闭包:把一堆变量封装起来,函数也是变量
第一层把name给封起来,第三层把son函数封装起来,
def father(name): def son(): print('form father %s' % name) print(locals())#打印当前层的局部变量 def grandson(): print('my grandson is %s' %name) grandson() son() father('alex')
装饰器的实现:@functionName : 语法糖
装饰器框架: import time def timmer(func): #高阶函数的特征一,参数是函数 def wrapper(): # print(func) start_time=time.time() func() stop_time=time.time() print('函数的运行时间是:%s' %(stop_time-start_time)) return wrapper #高阶函数的特征二,返回值是函数 @timmer #语法糖,相当于 test=timmer(test) 返回wrapper的地址 def test(): time.sleep(3) print('test函数运行完毕') test() #执行wrapper函数
为装饰器添加返回值
import time def timmer(func): def wrapper(): start_time=time.time() res=func() stop_time=time.time() print('函数运行时间是:%s' %(stop_time-start_time)) return res return wrapper
@timmer #=====>> timmer(test) def test(): time.sleep(3) return 'this is test value!!'
res=test() print(res)
为装饰器添加返回值
#两种传参方式
import time def foo(func): def wrap(*args,**kwargs): #第一种,此处传参 start_time=time.time() #res=func('Miracle',18,'male') #第二种只在这里传参 res=func(*args,**kwargs) #第一种,此处也传参 stop_time=time.time() print('函数运行的时间是:%s' %(stop_time-start_time)) return res return wrap @foo def task(name,age,gender): time.sleep(2) print('test凹函数运行完毕,名字是【%s】,年龄是【%s】,性别是【%s】' %(name,age,gender)) return '这里是test的返回值' print(task('Miralce',10,'female')) #第一种,此处传实参
利用装饰器制作验证功能:
user_dic={'username':None,'login':False} #利用一个全局变量进行存储状态 def auth_func(func): #写一个装饰器起到验证作用 def wrapper(*args,**kwargs): if user_dic['username'] and user_dic['login']: #验证是否已经登陆成功 res=func(*args,**kwargs) return res username=input('用户名:').strip() passwd=input('密码:').strip() if username == 'Miracle' and passwd == '123': user_dic['username']=username user_dic['login']=True res=func(*args,**kwargs) return res else: print('用户名或密码错误') return wrapper @auth_func def index(): print('welcome to JD host page!!') @auth_func def home(name): print('%s欢迎回家!!' %name) @auth_func def shopping_car(name): print('%s的购物车内有[%s,%s,%s]' %(name,'M','I','R')) index() home('帅哥') shopping_car('Miracle')
#验证功能高级玩法 user_list=[ {'user':'alex','passwd':'123'}, {'user':'Miracle','passwd':'1024'}, {'user':'xtznb','passwd':'abcd'}, {'user':'excellent','passwd':'anzhenshuai'} ] current_dic={'user':'None','login':False} #定义一个全局变量用于存储登陆状态 def auth_advance(func): def wrapper(*args,**kwargs): if current_dic['user'] and current_dic['login']: res=func(*args,**kwargs) return res username=input('用户名:').strip() passwd=input('请输入正确的密码:').strip() for user_dic in user_list: if username == user_dic['user'] and passwd == user_dic['passwd']: current_dic['user']=username current_dic['login']=True res=func(*args,**kwargs) return res else: print('用户名或密码错误!!') return wrapper @auth_advance def index(): print('welcome to JD host page!!') @auth_advance def home(name): print('welcome to home %s' % name) @auth_advance def shopping_car(name): print('%s的购物车内有[%s,%s,%s]' % (name, 'MM', 'TT', 'wawa')) index() home('Miracle') shopping_car('Miracle')
从文件中读取数据进行验证的超神玩法
#验证功能高级玩法 current_dic={'user':'None','login':False} #定义一个全局变量用于存储登陆状态 def auth_advance(func): def wrapper(*args,**kwargs): if current_dic['user'] and current_dic['login']: res=func(*args,**kwargs) return res username = input('用户名:').strip() passwd = input('密码:').strip() fi=open('Userdb',mode='r',encoding='utf-8') file=fi.readlines() for user_dic in file: user_dic=eval(user_dic) if username == user_dic['user'] and passwd == user_dic['passwd']: current_dic['user']=username current_dic['login']=True res=func(*args,**kwargs) return res else: print('用户名或密码错误!!') return wrapper @auth_advance#(auth_type='ldap') def index(): print('welcome to JD host page!!') @auth_advance def home(name): print('welcome to home %s' % name) @auth_advance def shopping_car(name): print('%s的购物车内有[%s,%s,%s]' % (name, 'M', 'I', 'wawa')) index() home('Miracle') shopping_car('Miracle')
带参数的装饰器用法:
带参数的验证功能装饰器 user_list=[{'user':'alex','passwd':'123'}, {'user':'Miracle','passwd':'1024'}, {'user':'znb','passwd':'abcd'}] def auth(auth_type='filedb'): def auth_func(func): def wrapper(*args, **kwargs): if auth_type == 'filedb': if current_code['username'] and current_code['login']: res = func(*args, **kwargs) return res username = input('loginName:').strip() passwd = input('password:').strip() for user_dic in user_list: if user_dic['user'] == username and user_dic['passwd'] == passwd: current_code['username'] = username current_code['login'] = True res = func(*args, **kwargs) return res else: print('真是Sorry,您输错了!!') elseif: auth_type == 'mysql' print('123') return wrapper return auth_func @auth(auth_type='maysqL') # (auth_type='filedb') #brakfast=auth(auth_type) def breakfast(bre): print('欢迎来吃早餐%s' % bre) breakfast('eggs!') current_code={'username':None,'login':False}