装饰器
装饰器:本质就是为其他函数添加附加功能
原则:
1.不修改被修饰函数的源代码
2.不修改被修饰函数对调用方式
装饰器的知识储备
装饰器=高阶函数+函数嵌套+闭包
高阶函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
例子:函数的参数是一个函数名
import time def foo(): time.sleep(3) print("hello") def test(func): #print(func) #内存地址 start_time=time.time() func() stop_time=time.time() print("函数运行时间是%s"%(stop_time-start_time)) test(foo)
写一个装饰器
例子1.多运行了一次,不合格
import time def foo(): time.sleep(3) print("hello") def timer(func): #print(func) #内存地址 start_time=time.time() func() stop_time=time.time() print("函数运行时间是%s"%(stop_time-start_time)) return func foo=timer(foo) foo()
例子:函数嵌套与作用域回顾
def father(name): print("form father %s"%name) def son(): print("my father is %s"%name) #先从本层找name变量,没有就从上一层找 print(locals()) #显示所有局部变量 son() father("steven")
装饰器实现
1、装饰器的架子
import time def timmer(func): #func=test def wrapper(): #print(func) start_time=time.time() func() #就是在运行test() stop_time=time.time() print("函数运行时间是%s"%(stop_time-start_time)) return wrapper @timmer def test(): time.sleep(3) print("test函数运行完毕") #test=timmer(test) 返回的是wrapper的地址 test() #执行的是wrapper() #@timmer() 就相当于test=timmer(test)
2、有返回值的情况,获取返回值
import time def timmer(func): def wrapper(): start_time=time.time() res=func() #就是在运行test() stop_time=time.time() print("函数运行时间是%s"%(stop_time-start_time)) return res return wrapper @timmer def test(): time.sleep(3) print("test函数运行完毕") return "test函数的返回值" res=test() #执行的是wrapper() print(res)
3、函数闭包加上参数
import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) #就是在运行test() stop_time=time.time() print("函数运行时间是%s"%(stop_time-start_time)) return res return wrapper @timmer def test(name,age): time.sleep(3) print("test函数运行完毕,名称%s,年龄%s"%(name,age)) return "test函数的返回值" res=test("张三",18) #执行的是wrapper() print(res)
4、补充,解压序列
a,b,c=(1,2,3) #解压序列 >>> a,b,c=(1,2,3) >>> a 1 >>> b 2 >>> c 3 >>> l=[2,4,2,3,5,7,8,9,5] >>> l [2, 4, 2, 3, 5, 7, 8, 9, 5] >>> a,*_,c=l # *代表中间所有的,下划线无意义,可以放一个变量名 >>> a 2 >>> c 5 >>> a,*d,c=l >>> a 2 >>> d #表示取中间所有的 [4, 2, 3, 5, 7, 8, 9] >>> c 5 >>> l [2, 4, 2, 3, 5, 7, 8, 9, 5] >>> a,b,*_,c,d (2, 2, 4, 2, 3, 5, 7, 8, 9, 5, [4, 2, 3, 5, 7, 8, 9]) >>> b 2
举例,a=1,b=2。把两个值互换
#方法一 >>> a=1 >>> b=2 >>> x=a >>> a=b >>> b=x >>> a,b (2, 1) #方法二 >>> f1=1 >>> f2=2 >>> f1,f2=f2,f1 >>> f1,f2 (2, 1)
装饰器应用
验证功能装饰器
购物网站举例,略
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=='job' 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("欢迎来到京东主页") @auth_func def home(name): print("欢迎你回家%s"%name) @auth_func def shopping_car(name): print("%s购物车里有笔,手机,电脑"%name) index() home("产品经理") shopping_car("产品经理")
复杂的例子
#增加了用户
user_list=[{"name":"steve","passwd":"123"}, {"name":"mark","passwd":"123"}, {"name":"jobs","passwd":"123"}] current_dic={"username":None,"login":False} def auth_func(func): def wrapper(*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["name"] and passwd==user_dic["passwd"]: current_dic["username"]=username current_dic["login"]=True res=func(*args,**kwargs) return res else: print("用户名或密码错误") return wrapper @auth_func def index(): print("欢迎来到京东主页") @auth_func def home(name): print("欢迎你回家%s"%name) @auth_func def shopping_car(name): print("%s购物车里有笔,手机,电脑"%name) index() home("产品经理") shopping_car("产品经理")
带参数装饰器
user_list=[{"name":"steve","passwd":"123"}, {"name":"mark","passwd":"123"}, {"name":"jobs","passwd":"123"}] current_dic={"username":None,"login":False} def auth(auth_type='filedb'): def auth_func(func): def wrapper(*args,**kwargs): print("认证类型是",auth_type) if auth_type=='filedb': 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["name"] and passwd==user_dic["passwd"]: current_dic["username"]=username current_dic["login"]=True res=func(*args,**kwargs) return res else: print("用户名或密码错误") elif auth_type=='ldap': print("ldap认证") res=func(*args,**kwargs) return res else: print("不知道的认证类型") res=func(*args,**kwargs) return res return wrapper return auth_func @auth(auth_type="filedb") #auth_func=auth(auth_type="filedb")-->@auth_func 附加了一个auth_type def index(): print("欢迎来到京东主页") @auth(auth_type='ldap') def home(name): print("欢迎你回家%s"%name) @auth(auth_type='haha') def shopping_car(name): print("%s购物车里有笔,手机,电脑"%name) index() home("产品经理") shopping_car("产品经理")