Flask(五) 异常、钩子、上下文

139 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

11. 异常

11.1 视图快速返回异常

在视图中返回http错误异常码,可以通过我们上文中的make_response来构建,也可以通过return来返回,还有一种更快速的方法:

abort

from flask import Flask, abort, request
app = Flask(__name__)


@app.route("/param_exception")
def get_app_route():
    user_id = request.args.get("user_id")
    if user_id is None:
        abort(400)
    return user_id

如果入参为空,直接返回400参数异常,如果不为空,返回入参

效果:

\

11.2 捕获异常

flask提供了对异常的统一处理,使用app.errorhandler进行统一处理.

当视图中出现异常时,并不是直接把异常抛出,返回给前台,flask会先寻找是否对此异常有处理,如果有,先走处理程序.

示例:

from flask import Flask

app = Flask(__name__)


@app.errorhandler(ZeroDivisionError)
def handle_zero_exception(e):
    print(e)
    return "自定义异常处理: 除数不能为零"


@app.route("/handle_exception")
def handle_exception():
    print(1 / 0)
    return "一切正常"

如果没有@app.errorhandler

做了异常处理后:

\

12. 钩子

flask提供了请求钩子来处理从请求开始到结束的准备或者扫尾工作.

比如每次请求需要验证登录,请求结束后需要设置header给浏览器,都可以通过请求钩子来完成.

请求钩子一共有四个

分别是:

  • before_first_request 第一次请求前执行
  • before_request 每次请求前执行
  • after_request 每次请求结束后,如果无异常抛出执行
  • teardown_request 每次请求结束执行

钩子的执行顺序为:

before_first_request -> before_request -> after_request ->teardown_request

\

flask采用了装饰器的方式允许对一个视图从请求到结束进行补充处理.

示例:

from flask import Flask

app = Flask(__name__)


@app.route("/")
def index():
    return "hello world"


@app.before_first_request
def before_first_request():
    print("before_first_request")


@app.before_request
def before_request():
    print("before request")


@app.after_request
def after_request(response):
    print("after request")
    return response


@app.teardown_request
def teardown_request(error):
    print("teardown request")

效果:

\

13. 上下文

上面我们使用过request全局对象,其实request是一个上下文对象,上下文对象在同一个场景/线程下是同一个对象.

而flask提供的上下文对象又分为会话级别和应用级别:

会话级别:

  • request
  • session

应用级别:

  • current_app
  • g对象

其中request和session都已经使用过了,而current_app我们来详细说一下

13.1 current_app

current_app其实获取的就是我们创建的flask对象, 在某些情况下,我们需要在蓝图中获取应用级别的配置文件,此时就可以通过current_app来获取.

示例:

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情

主应用:

from flask import Flask
from current_app import bp

app = Flask(__name__)
app.config["test_config"] = "123"

# 注册蓝图
app.register_blueprint(bp, url_prefix="/current")

蓝图:

from flask import Blueprint, current_app

bp = Blueprint('current_app', __name__)


# 定义蓝图视图,访问时打印应用配置文件
@bp.route("/current")
def get_current_config():
    print(current_app.config["test_config"])
    return "hello current_app"

\

效果:

通过current_app可以获取到应用上下文.