Flask源码流程剖析
在此之前需要先知道类和方法,个人总结如下:
2.类是type创建,创建类时候type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)
# 第0步: 执行type的 __init__ 方法【类是type的对象】
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
pass
第1步: 执行type的 __call__ 方法
1.1 调用 Foo类(是type的对象)的 __new__方法,用于创建对象。
1.2 调用 Foo类(是type的对象)的 __init__方法,用于对对象初始化。
obj = Foo()
# 第2步:执行Foodef __call__ 方法
obj()
再来我们以下面例子作为参考
from flask import Flask app = Flask(__name__) @app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
app.run()
1,首先执行Flask类的__call__方法:
class RequestContext(object):
def __init__(self,environ):
self.environ = environ def push(self):
# 3
# 请求相关数据,加到local中: stack.push...
_request_ctx_stack.push(self) # 获取cookie中的随机字符串,检验是否有,没有就生成
# 根据随机字符串,获取服务端保存的session的
# {
# 'xxxxxxx': {...}
# 'xxxxxxx': {...}
# }
# 新用户: {}
# 老用户:{user:'xxx'}
self.session = self.app.open_session(self.request)
if self.session is None:
self.session = self.app.make_null_session() class Flask:
def process_response(self, response):
# 8
# 执行 after_request装饰器
for handler in funcs:
response = handler(response) # 将内存中的session持久化到:数据库、....
if not self.session_interface.is_null_session(ctx.session):
self.save_session(ctx.session, response) return response def finalize_request(self, rv, from_error_handler=False):
# 7
response = self.make_response(rv)
try:
response = self.process_response(response)
request_finished.send(self, response=response)
except Exception:
if not from_error_handler:
raise
self.logger.exception('Request finalizing failed with an '
'error while handling an error')
return response def full_dispatch_request(self):
# 5 # 触发只执行一次的装饰器函数,@before_first_request
self.try_trigger_before_first_request_functions()
try:
# 触发Flask的信号,没用: pip3 install blinker
request_started.send(self) # 执行特殊装饰器:before_request
# 如果没有返回值,rv=None;有返回值 “嘻嘻嘻”
rv = self.preprocess_request()
if rv is None:
# 触发执行视图函数
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e) # 6 对返回值进行封装
return self.finalize_request(rv) def wsgi_app(self, environ, start_response): # 处理request,将请求添加到local中
ctx = self.request_context(environ)
# 2.处理request和session
ctx.push() error = None
try:
try:
# 4 执行视图函数
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
# 9
ctx.auto_pop(error) def __call__(self, environ, start_response):
"""Shortcut for :attr:`wsgi_app`."""
return self.wsgi_app(environ, start_response)
1,执行Flask的__call__方法
2,wsgi_app(request_context(environ),push) 对request和session的处理,第一次进来session为None,进行push
3,请求相关数据,加到local中: stack.push。获取cookie中的随机字符串,检验是否有,没有就生成根据随机字符串,获取服务端保存的session的
4,执行视图函数 full_dispatch_request()
5,触发只执行一次的装饰器函数,@before_first_request > ( 触发Flask的信号,没用: pip3 install blinker) > 执行特殊装饰器:before_request 如果没有返回值,rv=None;有返回值 ,rv=" 返回值 "
6 , 对返回值进行封装 return self.finalize_request(rv)
7 , 对封装的数据进行处理,并返回 response
8 , 执行 process_response(self, response): 执行 after_request装饰器 将内存中的session持久化到:数据库、redis、 ....
9 , 最后返回数据,并进行 ctx.auto_pop(error)
Flask源码流程剖析的更多相关文章
- Flask源码流程分析(一)
Flask源码流程分析: 1.项目启动: 1.实例化Flask对象 1. 重要的加载项: * url_rule_class = Rule * url_map_class = Map * session ...
- Flask 源码流程,上下文管理
源码流程 创建对象 from flask import Flask """ 1 实例化对象 app """ app = Flask(__na ...
- 07 flask源码剖析之用户请求过来流程
07 Flask源码之:用户请求过来流程 目录 07 Flask源码之:用户请求过来流程 1.创建ctx = RequestContext对象 2. 创建app_ctx = AppContext对象 ...
- flask源码剖析系列(系列目录)
flask源码剖析系列(系列目录) 01 flask源码剖析之werkzurg 了解wsgi 02 flask源码剖析之flask快速使用 03 flask源码剖析之threading.local和高 ...
- 08 Flask源码剖析之flask拓展点
08 Flask源码剖析之flask拓展点 1. 信号(源码) 信号,是在flask框架中为我们预留的钩子,让我们可以进行一些自定义操作. pip3 install blinker 2. 根据flas ...
- flask 源码剖析
flask 上下文管理源码流程及涉及的部分技术点 [flask源码梳理]之一 偏函数_mro [flask源码梳理]之二 面向对象中__setattr__ [flask源码梳理]之三 Local ...
- Python Web Flask源码解读(一)——启动流程
关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...
- 01 flask源码剖析之werkzurg 了解wsgi
01 werkzurg了解wsgi 目录 01 werkzurg了解wsgi 1. wsgi 2. flask之werkzurg源码流程 3. 总结 1. wsgi django和flask内部都没有 ...
- Flask源码剖析详解
1. 前言 本文将基于flask 0.1版本(git checkout 8605cc3)来分析flask的实现,试图理清flask中的一些概念,加深读者对flask的理解,提高对flask的认识.从而 ...
随机推荐
- 青否云 - 小程序待办事项 jquery开源系统
青否云最新开源系统:小程序待办事项 jquery-demo 青否云 Jquery demo 下载地址:https://github.com/qingful/jquery-demo 官网 http:// ...
- MVC+EF 入门教程(四)
一.前言 写了那么久,那么现在给大家看效果了 二.效果展示 点击创建Blog 显示 编辑 编辑成功,是不是很酷. 删除 终于完成了,准备睡觉!虽然有很多不足的地方,我会慢慢的去改的.感谢累了一天的自己 ...
- git 设置和取消代理
# 设置ss git config --global http.proxy 'socks5://127.0.0.1:1080' git config --global https.proxy 'soc ...
- mysql版本升级
环境 mysql安装在centos上,需要升级. mysql的版本是 mysql> select version(); +-----------+ | version() | +-------- ...
- springMVC(4)---生成excel文件并导出
springMVC(4)---生成excel文件并导出 在开发过程中,需要将数据库中的数据以excel表格的方式导出. 首先说明.我这里用的是Apache的POI项目,它是目前比较成熟的HSSF接口, ...
- bzoj 4196: [Noi2015]软件包管理器
Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...
- SQL Server中varchar和nvarchar的区别
varchar(n) 长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 1 和 8,000 之间的数值.存储大小为输入数据的字节的实际长度,而不是 n 个字节.nvar ...
- 二:mysql安装配置、主从复制配置详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8213723.html 邮箱:moyi@moyib ...
- PHP重要知识点
1 获取文件名或目录路径 getcwd() :显示是 在哪个文件里调用此文件 的目录 __DIR__ :当前内容写在哪个文件就显示这个文件目录 __FILE__ : 当前内容写在哪个文件就显示这个文件 ...
- 一个IC软件工程师的2017年终工作总结
相比2016年的波澜起伏,2017多了一份平静和清淡.不过,平静的生活下,总有一颗飞向远方的心. 在这一年将近结束的时候,总结一下自己的工作,生活和学习.也顺便展望一下未来的2018,看看有哪些 美好 ...