Python3基础-装饰器
1、装饰器的介绍
1、装饰:被装饰对象添加新的功能,器 代指 器具/工具 2、装饰器:本质是函数,作用在不修改被装饰对象源代码和调用方式的前提下被装饰对象添加额外的功能 3、函数装饰器 分为: 无参装饰器、有参装饰器
4、函数嵌套+闭包+函数对象 == 装饰器
2、例子
为下述函数添加统计其执行时间的功能
import time def test(res): time.sleep(3) for i in range(10): res += 1 return res test(10) #函数执行
高阶函数=》装饰器
import time def test(res): time.sleep(3) for i in range(10): res += 1 return res def testfunc(func): start_time=time.time() #开始运行时间 func(10) stop_time=time.time() #结束运行时间 sumtime=stop_time-start_time print('run time is %s'%sumtime) testfunc(test) #若是其他函数需要统计函数运行时间,则也需要统一改成 testfunc(其他函数) #没有遵循不修改被装饰对象的调用方式
#无参装饰器 def test(): time.sleep(3) print("泥是谁吖。。。。") def testfunc(func): return func res=testfunc(test) res()
#若被装饰的是一个有参函数,便会抛出异常
#有参装饰器 import time def timer(func): def wapper(*args,**kwargs):#引用外部作用域的变量 func start_time = time.time() # 开始运行时间 res=func(*args,**kwargs) stop_time = time.time() # 结束运行时间 sumtime = stop_time - start_time print("函数运行时间%s"%sumtime) return res return wapper @timer def test(res): time.sleep(3) for i in range(10): res += 1 return res test(10) #函数执行
闭包
如果在一个函数的内部定义了另一个函数,外部的函数叫它外函数,内部的函数叫它内函数 1 、在一个外函数中定义了一个内函数。 2 、内函数里运用了外函数的临时变量。 3 、并且外函数的返回值是内函数的引用。
#testouter是外部函数,x和y都是外函数的临时变量 def testouter(x): y=10 #inner是内部函数 def inner(): #在内函数中,用到了外函数的临时变量 print("输入的值:%d"%(x+y)) #外函数的返回值是内函数的引用 return inner demo=testouter(5) #此时外函数两个临时变量 x是5 y是10 ,并创建了内函数,然后把内函数的引用返回存给了demo # 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数 demo() # demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数 """
总结
1、一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。 2、闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。 """
======================================================================================================================================================
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{'username':'susu','passwd':'123'} {'username':'susu1','passwd':'123'} {'username':'susu2','passwd':'123'} {'username':'susu3','passwd':'123'} {'username':'susu4','passwd':'123'}
#登录认证 current_dic={'username':None,'login':False} #类似登录session 保存登录信息 只要登录一次就保存 def auth(auth_type='filedb'): def auth_func(func): def wrapper(*args,**kwargs): print('认证类型',auth_type) if current_dic['username'] and current_dic['login']: #判断是否已登录 res = func(*args,**kwargs) return res name=input("请输入账号>>>").strip() passwd=input("请输入密码 >>>").strip() if auth_type =='filedb': #判断读取文件类型 with open('filedb','r+') as f: #打开文件 for line in f: #一行一行的读取文件 user_dict=eval(line) #字符串类型转换成字典类型 # print('-----',user_dict) if name == user_dict['username'] and passwd ==user_dict['passwd']: current_dic['username'] = name current_dic['login'] = True res = func(*args, **kwargs) return res else: print("账号和密码错误") elif auth_type == 'ldap': print("不知道什么类型数据哭") return wrapper return auth_func @auth(auth_type='filedb') #auth_func=auth(auth_type='filedb') -->@auth_func 附加了一个auth_type -->index=auth_func(index) def inder(): print("欢迎来到京东页面") @auth(auth_type='ldap') def home(name): print("hi,%s.下午好"%name) @auth(auth_type='filedb') def shopping_cart(name): print("hi,%s,你的购物车里面有上衣、玻璃球、飞机玩具"%name) print('after--->',current_dic) inder() # home('susu') # shopping_cart('XiaoSu') print('before--->',current_dic)