持续创作,加速成长!这是我参与「掘金日新计划 · 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可以获取到应用上下文.