python装饰器语法糖_python装饰器 语法糖

简介:

装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。

比如说我们写flask,路由就是用装饰器定义的。如果写权限控制,那么权限控制一般也是由装饰器来实现的。日志记录,一般也可以通过装饰器来实现。

简单说,就是为了给某些函数增加一种或几种功能的做法。

下面举例实现。

一:基本函数

1.源码

from time importsleepdefwatch_movie():print('看电影')

sleep(3)print('The End')if __name__ == '__main__':

watch_movie()

View Code

2.执行结果

代码很简单,先打印看电影,间隔3秒,打印The End。

二:装饰器原理

1.目标:计算函数运行时间

2.源码

from time importsleep, timedefceal_time():

before=time()

watch_movie()

after=time()print('函数运行%s秒' % (after -before))defwatch_movie():print('看电影')

sleep(3)print('The End')if __name__ == '__main__':

ceal_time()

View Code

3.执行结果

代码很简单,先打印看电影,间隔3秒,打印The End,然后打印函数运行计时。

4.分析

我们把一个函数放进另一个函数去运行,这就是装饰器的基本工作原理。

三:改造计时函数为通用函数

1.目标:把计算函数运行时间这个功能,适配给不同的函数。

2.源码

from time importsleep, timedefceal_time(fun):

before=time()

fun()

after=time()print('函数运行%s秒' % (after -before))defwatch_movie():print('看电影')

sleep(3)print('The End')defplay_game():print('玩游戏')

sleep(3)print('Game Over')if __name__ == '__main__':

ceal_time(watch_movie)

ceal_time(play_game)

View Code

3.执行结果

看电影和玩游戏两个函数都执行了。

4.分析

我们可以把函数作为对象,传入另一个函数当中。

四:变为装饰器

1.目标:

我们改变了函数的调用方式,能不能不改变函数在调用位置的代码呢?

2.源码:

from time importsleep, timedefceal_time(fun):defwrapper():

before=time()

fun()

after=time()print('函数运行%s秒' % (after -before))returnwrapper

@ceal_timedefwatch_movie():print('看电影')

sleep(3)print('The End')#@ceal_time

defplay_game():print('玩游戏')

sleep(3)print('Game Over')if __name__ == '__main__':

watch_movie()

play_game()

View Code

3.执行结果

看电影前面加了装饰器,实现了函数运行计时,玩游戏没有加装饰器,所以没有函数运行计时。

而且函数在main中的调用方式和没加装饰器是一样的。

五:函数有参数

1.目标:被装饰的函数,有参数的处理

2.源码:

from time importsleep, timedefceal_time(fun):def wrapper(*args, **kwargs): #修改

before =time()

fun(*args, **kwargs) #修改

after =time()print('函数运行%s秒' % (after -before))returnwrapper

@ceal_timedefwatch_movie(name, movie):print('%s在看%s电影' %(name, movie))

sleep(3)print('The End')#@ceal_time

defplay_game(name, game):print('%s在玩%s游戏' %(name, game))

sleep(3)print('Game Over')if __name__ == '__main__':

watch_movie(name='张三', movie='猫和老鼠')

play_game(name='李四', game='魔兽争霸')

View Code

3.执行结果

你可以试试看,没有了*args,**kwargs,一定是会报错的。

六:有返回值的函数加装饰器

1.目标:现在做的都没返回值,如何处理被装饰的函数的返回值。

2.源码:

from time importsleep, timedefceal_time(fun):def wrapper(*args, **kwargs):

before=time()

result= fun(*args, **kwargs) #修改

after =time()print('函数运行%s秒' % (after -before))return result #返回

returnwrapper

@ceal_timedefwatch_movie(name, movie):print('%s在看%s电影' %(name, movie))

sleep(3)print('The End')return '电影看完了'

#@ceal_time

defplay_game(name, game):print('%s在玩%s游戏' %(name, game))

sleep(3)print('Game Over')return '游戏玩完了'

if __name__ == '__main__':print(watch_movie(name='张三', movie='猫和老鼠'))print(play_game(name='李四', game='魔兽争霸'))

View Code

3.执行结果

现在已经可以处理任何函数的装饰器操作了。

七:权限登录

1.目标:

flask中未登录用户进入登录页面

flask中登录用户进入详情页面

2.源码一(无装饰器):

无装饰器,简单判断session存在即可进入。

importosfrom flask importFlask, request, g, redirect, url_for, session

app= Flask(__name__)

app.config['SECRET_KEY'] = os.urandom(24)defceal_time(fun):def wrapper(*args, **kwargs):

result= fun(*args, **kwargs) #修改

return result #返回

returnwrapper

@app.route('/')defindex():return '欢迎页面'@app.route('/login/', methods=['GET', 'POST'])deflogin():if request.method == 'GET':

html= '''

用户名:
密码:
'''

returnhtmlif request.method == 'POST':

session['sign'] =Truereturn redirect(url_for('info'))return '登录'@app.route('/info/')definfo():if session.get('sign'):return '详情页'

else:return redirect(url_for('login'))if __name__ == '__main__':

app.run()

View Code

3.源码二(有装饰器):

importosfrom flask importFlask, request, g, redirect, url_for, session

app= Flask(__name__)

app.config['SECRET_KEY'] = os.urandom(24)defcheck_auth(fun):def wrapper(*args, **kwargs):if session.get('sign'):return fun(*args, **kwargs) #修改

else:return redirect(url_for('login'))returnwrapper

@app.route('/')defindex():return '欢迎页面'@app.route('/info/')

@check_authdefinfo():return '详情页'@app.route('/login/', methods=['GET', 'POST'])deflogin():if request.method == 'GET':

html= '''

用户名:
密码:
'''

returnhtmlif request.method == 'POST':

session['sign'] =Trueprint(session.get('sign'))return redirect('/info/')#return redirect(url_for('info')) #这里写url_for会出错,但是session也创建成功,直接硬跳转吧。

if __name__ == '__main__':

app.run()

四:验证

1,访问http://127.0.0.1:5000/       欢迎页面

2,访问http://127.0.0.1:5000/login    登录页面

3,访问http://127.0.0.1:5000/info     自动进入登录页面,

4,登录页面点击提交,进入login的POST模式,设置session,然后自动进入详情页面。

5,装饰器的登录验证就这样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值