装饰器这个在Flask里面咋用的啊!?
最近这句话在我身边无数次的响起~
咱们来看看对于解释。
装饰器解释:
装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。
这是what?!其实看字面意思,似乎懂了,实际仍然不知道啥子意思。
来业务场景:
在一个论坛业务中,我们登录页面登录过后,跳转其他页面需要每次都判断我们的登录状态,但是每次重复写同样的代码,费事费力,还极其容易出错,有什么方法可以直接避开这样的问题呢?这就要用到装饰器,即使用装饰器的方法去查询登录状态。
传统的方法,遇到这种业务逻辑会将公用的代码抽取到一个方法中,但是这是相当的啰嗦,怎么破?
装饰器+g变量
=============================
#公共类
import functools
import flask import current
import flask import g
import flask import session
def check_login(f):
@functools.wraps(f) #核心部分,对内层函数wrapper进行装饰
def wrapper(*args,**kwargs):
uid = session.get("uid",None)
user = None
if uid:
try:
user = User.query.get(uid)
except Exception as e:
current_app.logger.error(e)
g.user = user #查询到的值赋予g变量
return f(*args,**kwargs)
return wrapper
#具体调用
@xxx_blur.route('xxxx')
@check_login
def newstalk(newsid):
user = g.user
pass
装饰器本质上是一个Python函数,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能。对于上边的代码,即抽离大量的与函数功能本身无关的雷同代码并发并继续使用。我们只需要将其保存在g变量中,用的时候调用函数即可。
其他:
1、g对象,用于保存数据。
2、关于functools_wraps函数
我们都还知道,装饰器装饰完之后,我们被装饰的函数的名字会变成装饰器函数的内层函数名。
即无论你打印多少,名字都会是你的内层函数名。而使用了functools.wraps就还原了原来的方法名。
说白了,functools.wraps保持了当前装饰器所装饰的函数__name__的值不变。
那么在我们的Flask项目里面,一个视图函数不能被两个不同的路由进行装饰,一个路由对应一个函数,否则就会出现覆盖,报错。