1.为什么要有装饰器?
为了给函数增加新功能,而且不改变函数自身代码,也不改变函数调用方式
2.装饰器原理?
闭包函数加语法糖
语法糖自动实现“偷梁换柱”(在被装饰函数的上方一行加上@装饰器名)
闭包函数中内层函数用来实现新功能,并且调用原来的函数
3.装饰器结构
3个函数:外层函数(用来传入被装饰函数),内层函数(1.调用被装饰函数 2.增添新的功能),被装饰函数
1.外层函数:仅仅用来传被装饰函数(闭包函数其实是一种传参方式,因为内层为了接受任意被装饰函数的参数,形参是*args和**kwrags,不能再加形参了)
2.内层函数:1.调用原来函数:对内层函数传入参数*args和**kwargs,使被装饰函数的参数完全得到复制。记得最后接受返回值。
2.增添新功能
4.装饰器模板(见单独的代码)
def outter(func):
def wrapper(*args,**kwargs):
#装饰的开始
res = func(*args,**kwargs)
return res
return wrapper
5.小项目
(1)计时装饰器
import time
def outter(func):
def wrapper(*args,**kwargs):
s = time.time()
res = func(*args,**kwargs)
e = time.time()
print(e - s)
return res
return wrapper
@outter
def index(x,y):
time.sleep(2)
print(f'index is {x} and {y}')
index('2asf','sadf')
2.用户登录认证装饰器(登录超时需要重新登录)
import time
def auth_plus(func):
def wrapper(*args, **kwargs):
login_dic = {}
with open('info.txt','r',encoding='utf-8')as f:
for linein f:
line = line.strip().split(',')
login_dic[line[0]] = line
# print(login_dic)
name =input('请输入用户名:')
if namein login_dic:
# print(login_dic[name][2])
if login_dic[name][2] =='1':
e = time.time()
s = login_dic[name][3]
# print(e,s)
if e -float(s) <20:
print(f'{name},欢迎回来')
res = func(*args, **kwargs)
return res
else:
password =input('登录超时,请重新输入密码:')
if login_dic[name][1] == password:
login_dic[name][2] ='1'
login_dic[name][3] =str(time.time())
with open('info.txt','w')as f:
for valin login_dic.values():
a =','.join(val) +'\n'
f.write(a)
print('登陆成功')
res = func(*args, **kwargs)
return res
else:
login_dic[name][2] ='0'
login_dic[name][3] ='0'
print('密码错误')
elif login_dic[name][2] =='0':
password =input('请输入密码:')
if login_dic[name][1] == password:
login_dic[name][2] ='1'
login_dic[name][3] =str(time.time())
with open('info.txt','w')as f:
for valin login_dic.values():
a =','.join(val) +'\n'
f.write(a)
print('登陆成功')
res = func(*args, **kwargs)
return res
else:
print('密码错误')
else:
print('账号不存在')
return wrapper
@auth_plus
def register():
print('注册')
@auth_plus
def transfer():
print('转账')
@auth_plus
def takeout():
print('取钱')
@auth_plus
def takein():
print('存钱')
@auth_plus
def check_banlance():
print('查询余额')
func_dic = {
'0':['退出',None],
'1':['注册',register],
'2':['转账',transfer],
'3':['取钱',takeout],
'4':['存钱',takein],
'5':['查询余额',check_banlance]
}
while True:
for indexin func_dic:
print(index,func_dic[index][0])
count =input('请输入要进行的操作:')
if not count.isdigit():
print('请输入数字,瞎子......')
continue
if count =='0':
exit('欢迎下次光临')
if countin func_dic:
func_dic[count][1]()
else:
print('只能输入指定编号,呆逼......')