装饰器:本质就是函数,功能是为其他函数添加附加功能
原则:
1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器的知识储备
装饰器=高阶函数+函数嵌套+闭包
#装饰器: def timmer(func): def wrapper(*args,**kwargs): time1=time.time() res=func(*args,**kwargs) time2=time.time() print('函数的运行时间是%d'%(time2-time1)) return res return wrapper @timmer def cal(l): res=0 for i in l: res+=i time.sleep(0.1) return res a=cal(range(10)) print(a) >>>函数的运行时间是1 45
高阶函数定义:
1.函数接收的是一个函数名
2.函数的返回值是一个函数名
3.满足上述任意一个条件都可以称之为高阶函数
import time def foo(): time.sleep(0.5) print("sadfa") def test(func): print(func) t1=time.time() func() t2=time.time() print("函数的运行时间是%ds"%(t2-t1)) test(foo)#修改了函数的调用方式
#不修改源代码 #不修改foo调用方式 #多运行了一次,不合格 def foo(): time.sleep(1) print("from the foo") def dec(func): t1=time.time() func() t2=time.time() print("%s的运行时间是%d"%(func,(t2-t1))) return func foo=dec(foo) foo()
函数的闭包:闭包是由函数及其相关的引用环境组合而成的实体,如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
def father(name): print('from father %s'%name) def son(): print('my father is %s'%name) def grandson(): print('my grandpa is %s'%name) grandson() son() print(locals()) father('alex') >>>from father alex my father is alex my grandpa is alex {'son': <function father.<locals>.son at 0x00000169A59B7268>, 'name': 'alex'}
装饰器框架:
#装饰器框架 def timmer(func): def wapper(): print(func) func() return wapper
def timmer_test(func): def add_time(): t1=time.time() func() t2=time.time() print('该函数的运行时间是%d'%(t2-t1)) return add_time def test(): time.sleep(2) print('test函数运行完毕') test=timmer_test(test) test()
>>>test函数运行完毕 该函数的运行时间是2
@语法糖:
def timmer(func): def add_time(): t1=time.time() func() t2=time.time() print('该函数的运行时间是%d'%(t2-t1)) return add_time @timmer#@timmer 就相当于test=timmer(test) def test(): time.sleep(2) print('test函数运行完毕') test() >>>test函数运行完毕 该函数的运行时间是2
函数闭包加上返回值:
def timmer(func): def add_time(): t1=time.time() res=func() t2=time.time() print('该函数的运行时间是%d'%(t2-t1)) return res return add_time @timmer#@timmer 就相当于test=timmer(test) def test(): time.sleep(2) print('test函数运行完毕') return '这是test的返回值' res=test()#这里就是在运行add_time print(res) >>>test函数运行完毕 该函数的运行时间是2 这是test的返回值
再加上参数:
def timmer(func): def add_time(*args,**kwargs): t1=time.time() res=func(*args,**kwargs) t2=time.time() print('该函数的运行时间是%d'%(t2-t1)) return res return add_time @timmer#@timmer 就相当于test=timmer(test) def test(name,age): time.sleep(2) print('test函数运行完毕,名字是%s,年龄是%d'%(name,age)) return '这是test的返回值' @timmer def test1(name,age,gender): time.sleep(3) print('test1函数运行完毕,名字是%s,年龄是%d,性别是%s'%(name,age,gender)) return '这是test1的返回值' res=test('alex',19)#这里的test是运行的add_time print(res) res1=test1('sb',20,'male') print(res1) >>>test函数运行完毕,名字是alex,年龄是19 该函数的运行时间是2 这是test的返回值 test1函数运行完毕,名字是sb,年龄是20,性别是male 该函数的运行时间是3 这是test1的返回值
解压序列:
a,b,c='hel' print(a,b,c) e,f,g=(4,5,6) print(e,f,g) #取出第一个值和最后两个值 l=['alex',7,8,9,7,8,5,2,1,5,6,4,8,6,4,6,'is','sb'] #*_代表中间所有的值,_可以换成任意值 x,*_,y,z=l print(x,y,z) >>>h e l 4 5 6 alex is sb
调换两变量的值:
a=20 b=100 a,b=b,a print(a,b) >>>100 20
装饰器加上验证功能:
user_dic={'name':None,'login':False} def yanzheng(func): global zt def wapper(*args,**kwargs): if user_dic['name'] and user_dic['login']: res=func(*args,**kwargs) return name=input('请输入用户名:').strip() psw=input('请输入密码:').strip() if name=='alex' and psw=='123': res=func(*args,**kwargs) user_dic['name']=name user_dic['login']=True return res else: print('用户名或密码错误') return wapper @yanzheng def index(): print('欢迎来到京东主页') @yanzheng def home(name): print('欢迎回家%s'%name) @yanzheng def car(name): print('%s的购物车里有%s'%(name,'奶茶')) index() home('alex') car('alex') >>>请输入用户名:alex 请输入密码:123 欢迎来到京东主页 欢迎回家alex alex的购物车里有奶茶
user_list=[ {'user_name':'alex','psw':'123'}, {'user_name':'blex','psw':'456'}, {'user_name':'clex','psw':'789'}, {'user_name':'dlex','psw':'0'} ] current_zt={'name':None,'login':False} def yanzheng(func): def wapper(*args,**kwargs): global user_name if current_zt['name'] and current_zt['login']: res=func(*args,**kwargs) return res user_name=input('请输入用户名:').strip() psw=input('请输入密码:').strip() for user_dic in user_list: if user_name==user_dic['user_name'] and psw==user_dic['psw']: res=func(*args,**kwargs) current_zt['name']=user_name current_zt['login']=True return res else: print('用户名或密码错误') return wapper @yanzheng def index(): print('欢迎来到京东主页') @yanzheng def home(): print('欢迎回家%s'%user_name) @yanzheng def car(): print('%s的购物车里有%s'%(user_name,'奶茶')) index() home() car() >>>请输入用户名:blex 请输入密码:456 欢迎来到京东主页 欢迎回家blex blex的购物车里有奶茶
将原装饰器加上参数:直接在最外层加一个函数带上参数,使用装饰器时也需带上参数
user_list=[ {'user_name':'alex','psw':'123'}, {'user_name':'blex','psw':'456'}, {'user_name':'clex','psw':'789'}, {'user_name':'dlex','psw':'0'} ] current_zt={'name':None,'login':False} def renzhen(type='ldb'): def yanzheng(func): def wapper(*args,**kwargs): global user_name print('认证类型是%s'%type) if type=='ldb': if current_zt['name'] and current_zt['login']: res=func(*args,**kwargs) return res user_name=input('请输入用户名:').strip() psw=input('请输入密码:').strip() for user_dic in user_list: if user_name==user_dic['user_name'] and psw==user_dic['psw']: res=func(*args,**kwargs) current_zt['name']=user_name current_zt['login']=True return res else: print('用户名或密码错误') elif type=='abb': print('不知道这个类型') res = func(*args, **kwargs) return res else: print('类型错误') res = func(*args, **kwargs) return res return wapper return yanzheng @renzhen(type='ldb') def index(): print('欢迎来到京东主页') @renzhen(type='abb') def home(): print('欢迎回家%s'%user_name) @renzhen(type='sss') def car(): print('%s的购物车里有%s'%(user_name,'奶茶')) index() home() car()