装饰器的概念:
1.装饰器的实现是由闭包支撑的;
2.装饰器本质上是⼀个python函数,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能;
3.装饰器的返回值也是⼀个函数的对象,它经常用于有切面需求的场景,实现路由传参,flask的路由传参依赖于装饰器,浏览器通过url访问到装饰器的路由,从而访问视图函数获得返回的HTML页面;
装饰器应用场景:
1.可以在外层函数加上时间计算函数,计算函数运行时间;
2.计算函数运行次数;
3.可以用在框架的路由传参上;
4.插入日志,作为函数的运行日志;
5.事务处理,可以让函数实现事务的一致性,让函数要么一起运行成功,要么一起运行失败;
6.缓存,实现缓存处理;
7.权限的校验,在函数外层套上权限校验的代码,实现权限校验;
为了进行过对比,下面会采用两种方式:1.不使用装饰器 2.使用装饰器 两种方式来实现支付时登陆校验这个功能。
#不使用装饰器
islogin=False #登陆状态初始值设置为False
def login(): #登陆函数
name=input('请输入用户名:')
pwd=input('请输入密码:')
if name=='admin' and pwd=='123456':
return True
else:
return False
def pay(money): #支付函数
global islogin #使用global声明可修改全局变量
if islogin: #登陆状态为True则执行以下付款代码
print('------付款------')
print('正在付款,付款金额是{}元'.format(money))
print('付款中……')
time.sleep(2)
print('付款成功')
else: #登陆状态为False则提示未登陆并调用登陆函数提示用户进行登陆操作
print('未登陆,请先登陆!')
islogin = login()
pay(100)
pay(90)
#使用装饰器
islogin=False #登陆状态初始值设置为False
def login(): #登陆函数
name=input('请输入用户名:')
pwd=input('请输入密码:')
if name=='admin' and pwd=='123456':
return True
else:
return False
def loginrequire(func): #装饰器-登陆校验函数
def inner(*args,**kwargs):
global islogin #使用global声明可修改全局变量
if islogin: #登陆状态为True则调用支付函数进行支付
func(*args,**kwargs)
else: #登陆状态为False则提示未登陆并调用登陆函数提示用户进行登陆操作
print('用户未登陆,请先登陆!')
islogin = login() #获取用户的登陆状态并更新状态值
return inner
@loginrequire
def pay(money): #支付函数,模拟支付操作
print('------付款------')
print('正在付款,付款金额是{}元'.format(money))
print('付款中……')
time.sleep(2)
print('付款成功')
pay(100)
pay(99)
运行结果都为:
用户未登陆,请先登陆!
请输入用户名:admin
请输入密码:123456
------付款------
正在付款,付款金额是99元
付款中……
付款成功
虽然看起来不使用装饰器时代码行数比使用装饰器时要少,但是使用装饰器的代码明显结构更清晰,拓展功能也更方便,每个函数各司其职,而不是侵入到原来的代码里面进行修改。