装饰器:
本质:就是一个函数
功能:为其他函数添加附加功能
原则:1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器=高阶函数+函数嵌套+闭包
高阶函数:结合两种高阶函数的方式,不能满足装饰器的功能,多执行了一次操作
import time def foo(): print("来自foo") def test(func): print("来自test") start_time=time.time() func() end_time=time.time() print("运行时间%s" %(start_time-end_time)) return func foo=test(foo) foo()
装饰器的基本实现:
import time def foo(func): #func=test def too(): start_time=time.time() func() end_time=time.time() print("运行时间%s" %(start_time-end_time)) return too @foo def test(): time.sleep(3) print("函数运行完毕") # test=foo(test) #修改了一部分源代码,可在函数前加上@foo(完成了test=foo(test)的操作),表示调用装饰器内容 # test() test()
ps:1.返回值的问题,保存test函数中的返回值,装饰器中需要有变量接收返回的值
import time def foo(func): #func=test def too(): start_time=time.time() res=func() #***接收test的返回值 end_time=time.time() print("运行时间%s" %(start_time-end_time)) return res #***最终返回res的值 return too @foo def test(): time.sleep(3) print("函数运行完毕") return "test的返回值" # test=foo(test) #返回的是too的地址 # test() #执行too # #修改了一部分源代码,可在函数前加上@foo(完成了test=foo(test)的操作),表示调用装饰器内容 res=test() print(res)
2. 加入参数,利用可变长参数接收各种类型的数据
import time def foo(func): #func=test def too(*args,**kwargs): #保证参数原封不动原给下一个func start_time=time.time() res=func(*args,**kwargs) end_time=time.time() print("运行时间%s" %(start_time-end_time)) return res return too @foo def test(name,age,gender): #(name,age,gender)=("alex",12,"male) 通过解压序列,获得一一对应的关系传入 time.sleep(3) print("函数运行完毕","我是%s,年龄为%s,性别是%s" %(name,age,gender)) return "test的返回值" res=test("alex",12,"male") print(res)
ps:解压序列:
取开头和结尾的值:
l=(1,23,4354,76,8,) a,*_,c=l #*_表示中间的全部数 print(a,c)
位置调换:
a1=1 a2=2 a1,a2=a2,a1 print(a1,a2)
加上验证功能例子:
user_list=[{"username":"alex","passwd":"123"},{"username":"sb","passwd":"abc"},{"username":"baby","passwd":"456"}] current_dic={"username":None,"login":False} def fangfa(func): def foo(*args,**kwargs): if current_dic["username"] 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["username"] and passwd== user_dic["passwd"]: current_dic["username"]=username current_dic["login"]=True res=func(*args,**kwargs) return res else: print("用户名或密码错误") return foo @fangfa def zhuye(*args,**kwargs): print("欢迎来到京东主页") @fangfa def home(name): print("%s欢迎回来" %name) @fangfa def shopping_car(name,m1,m2,m3): print("%s的购物车有[%s],[%s],[%s]" %(name,m1,m2,m3)) zhuye() home("sb") shopping_car("sb","奶茶","可乐","巧克力")
闭包(加上验证类型):最终版本
user_list=[{"username":"alex","passwd":"123"},{"username":"sb","passwd":"abc"},{"username":"baby","passwd":"456"}] current_dic={"username":None,"login":False} def total(user_type): ##闭包,函数最终运行的还是foo def fangfa(func): def foo(*args,**kwargs): if user_type == "ldap": print("认证类型%s" %user_type) if current_dic["username"] 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["username"] and passwd== user_dic["passwd"]: current_dic["username"]=username current_dic["login"]=True res=func(*args,**kwargs) return res else: print("用户名或密码错误") return elif user_list == "aaa": print("验证类型%s" %user_type) res=func(*args,**kwargs) return res else: print("用户验证类型%s错误" %user_type) res=func(*args,**kwargs) return res return foo return fangfa @total(user_type="ldap") def zhuye(*args,**kwargs): print("欢迎来到京东主页") @total(user_type="aaa") def home(name): print("%s欢迎回来" %name) @total(user_type="dasjdk") def shopping_car(name,m1,m2,m3): print("%s的购物车有[%s],[%s],[%s]" %(name,m1,m2,m3)) zhuye() home("sb") shopping_car("sb","奶茶","可乐","巧克力")