示例

from flask import Flask

app = Flask(__name__)

@app.before_request
def xx():
pass @app.route('/')
def index():
return 'index' if __name__ == '__main__':
app.run()

看如上代码,如果此时请求视图函数 index ,在视图函数执行之前, @app.before_request 装饰的函数在这里也就是 xx 会先执行。

源码

查看 before_request :

 @setupmethod
def before_request(self, f):
self.before_request_funcs.setdefault(None, []).append(f)
return f

flask.app.Flask.before_request

首先要知道在脚本加载时,被装饰器装饰的函数会被作为参数传入装饰器函数,在上面示例中也就是会将 xx 函数作为 before_request 函数的参数 f 传入。可以看到该装饰器函数就很简单两行,把函数 f 句柄添加到 app.before_request_funcs 列表中,对应示例中就是将 xx 函数的句柄添加到了 before_request_funcs 中。

紧接着,在请求到来时,会执行 app.wsgi_app 方法:

 def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)

flask.app.Flask.wsgi_app

进到第 7 行的 full_dispatch_request 方法:

 def full_dispatch_request(self):
self.try_trigger_before_first_request_functions()
try:
request_started.send(self)
rv = self.preprocess_request()
if rv is None:
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
return self.finalize_request(rv)

flask.app.Flask.full_dispatch_request

再进到第 5 行的 preprocess_request 方法:

 def preprocess_request(self):
bp = _request_ctx_stack.top.request.blueprint funcs = self.url_value_preprocessors.get(None, ())
if bp is not None and bp in self.url_value_preprocessors:
funcs = chain(funcs, self.url_value_preprocessors[bp])
for func in funcs:
func(request.endpoint, request.view_args) funcs = self.before_request_funcs.get(None, ())
if bp is not None and bp in self.before_request_funcs:
funcs = chain(funcs, self.before_request_funcs[bp])
for func in funcs:
rv = func()
if rv is not None:
return rv

flask.app.Flask.preprocess_request

看到第 10 行,从 self.before_request_funcs 拿到之前存入的方法,也就是也就是上面被 before_request 装饰器装饰的函数对应示例中的 xx ,接着在 13-16 行循环执行所有方法,如果有返回值则直接返回,到这里 before_request 的执行原理也就明了了。紧接着 flask.app.Flask.full_dispatch_request 中第 5 行接收到返回值,第 6、7 行判断如果返回值如果为空,才执行 self.dispatch_request 方法。而 self.dispatch_request 方法正是用来执行视图函数的。所以得出结论:如果 before_request 装饰器装饰的函数有返回值,那么将不会继续执行视图函数。

python框架之Flask(5)-@app.before_request原理的更多相关文章

  1. python框架之Flask(1)-Flask初使用

    Flask是一个基于 Python 开发并且依赖 jinja2 模板和 Werkzeug WSGI 服务的一个微型框架,对于 Werkzeug 本质是 Socket 服务端,其用于接收 http 请求 ...

  2. python框架之Flask(4)-上下文管理

    知识储备 偏函数 作用 偏函数,帮助开发者自动传递参数. 使用 import functools def index(a1, a2): return a1 + a2 # 原来的调用方式 # ret = ...

  3. python框架之Flask基础篇(二)-------- 数据库的操作

    1.flask连接数据库的四步: 倒入第三方数据库扩展包:from flask_sqlalchemy import SQLAlchemy 配置config属性,连接数据库: app.config[&q ...

  4. python框架之Flask

    介绍:Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 . WSGl:Web Server Gateway ...

  5. python框架之Flask(3)-Blueprint(蓝图)

    蓝图 用途 给开发者提供清晰的目录结构. 使用 目录结构 1.创建项目. 2.在项目目录下创建与项目名同名文件夹. 3.在 test_prj 文件夹下创建 __init__.py 文件,并在其中实例化 ...

  6. python框架之Flask基础篇(一)

    一.第一个hello world程序 # coding=utf-8 from flask import Flask app = Flask(__name__) @app.route('/') def ...

  7. python框架之Flask基础篇(三)-------- 模版的操作

    1.flask特有的变量和函数: 变量:g.session.request.config 函数:url_for().get_flashed_messages()这个函数注意了啊,记住这是个函数,别忘了 ...

  8. python框架之Flask(2)-路由和视图&Session

    路由和视图 这一波主要是通过看源码加深对 Flask 中路由和视图的了解,可以先回顾一下装饰器的知识:[装饰器函数与进阶] 路由设置的两种方式 # 示例代码 from flask import Fla ...

  9. python框架之Flask(6)-flask-sqlalchemy&flask-script&flask-migrate使用

    整合SQLAlchemy 安装 pip3 install flask-sqlalchemy 简单使用 from flask import Flask from flask_sqlalchemy imp ...

随机推荐

  1. 关于asyncio知识(四)

    一.使用 asyncio 总结 最近在公司的一些项目中开始慢慢使用python 的asyncio, 使用的过程中也是各种踩坑,遇到的问题也不少,其中有一次是内存的问题,自己也整理了遇到的问题以及解决方 ...

  2. Atitit r2017 r6 doc list on home ntpc.docx

    Atitit r2017 r6 doc list on home ntpc.docx 驱动器 D 中的卷是 p2soft 卷的序列号是 9AD0-D3C8 D:\ati\r2017 v4 raf\r2 ...

  3. ES容易忽视的集群配置

    一 前言 目前生产系统由Solr转ES了,在这边就记录下在使用过程中容易忽视的配置吧,其实我也是才用,如果有什么错误的地方,多指正. 二.配置 1.ES的段合并是限速设置 默认是20MB/s ,如果是 ...

  4. 【WPF】ImageMagick调节图片的颜色

    需求:打开一张图片后,自由调节图片的颜色(色调). 思路:读取显示一张图片后,用ColorPicker取色器选择一种颜色,之后将图片的色调调节为该颜色. 工具: 1.图像工具 ImageMagick( ...

  5. power designer 16.5 使用总结[转]

    测试环境:power designer 16.5.vs2010.win7 对于破解版的power designer经常出现崩溃.停止工作的情况 请运行pdlegacyshell16.exe,不要运行P ...

  6. 关于QQ邮箱有时候接受不到邮件的解决

    1.很可能是被当作垃圾邮件拦截了,这时候就要自己找回 2.首先点击邮箱首页 3.在最后一行倒数第三个选择自助查询 4.一般在收信查询或者删信查询里面,找到被删的邮件,添加到白名单就好了

  7. Deseq2 的可视化策略汇总

    1) MA图   对于MA图而言, 横坐标为该基因在所有样本中的均值,basemean = (basemean_A + basemean_B ) / 2, 纵坐标为 log2Fold change 其 ...

  8. 使用100%面向过程的思维方式来写java程序

    1.java是强制写class关键字的语言,不能有独立的函数游离在类外出现在文件中,这和python c++ 都不同,后面的都可以单独在类外写函数,所以java被称为是纯面向对象的语言,py和c++都 ...

  9. osg shader 相机观察矩阵逆矩阵 求顶点世界坐标

    uniform mat4 osg_ViewMatrixInverse;//osg内置uniform void main() { vec4 posWorld = osg_ViewMatrixInvers ...

  10. navicat for mysql cant connect to server 10038 远程连接出错

    使用的登录账号没有开通远程登录的权限,所以只能在服务器上通过命令行登录. 解决办法如下:1.在服务器上通过命令行或客户端登录mysql:2.执行以下sql:GRANT ALL PRIVILEGES O ...