flask基础之AppContext应用上下文和RequestContext请求上下文(六)
前言
应用上下文和请求上下文存在的目的,官方文档讲的很清楚,可参考:
http://www.pythondoc.com/flask/appcontext.html
应用上下文对象在没有请求的时候是可以单独存在的,但是请求上下文对象只有在收到请求后才会被创建。请求处理和应用上下文和请求上下文的关系是:
接收请求--》创建请求上下文--》请求上下文入栈--》创建该请求的应用上下文--》应用上下文入栈--》处理逻辑--》请求上下文出栈--》应用上下文出栈
系列文章
请求上下文RequestContext
请求上下文管理着请求对象Request,会话对象Session,当前请求的app应用,为了保证在一个请求的周期内的任何时候任何地点访问到Request和Session,又不能发生循环导入的问题,flask使用代理对象request和session来代理当前请求的Request和Session。
request = LocalProxy(partial(_lookup_req_object, 'request'))
session = LocalProxy(partial(_lookup_req_object, 'session'))
RequestContext分析
flask框架处理请求的第一步就是收到请求后创建请求上下文RequestContext.
class RequestContext(object):
def __init__(self, app, environ, request=None):
self.app = app
if request is None:
request = app.request_class(environ) # 使用app的Request对象创建一个实例
self.request = request # 请求上下文的request
self.url_adapter = app.create_url_adapter(self.request)
self.flashes = None
self.session = None # 请求上下文的session
self._implicit_app_ctx_stack = [] # 请求上下文的应用上下文临时存放点
self.preserved = False
self._preserved_exc = None
self._after_request_functions = []
self.match_request() # 提取请求的路由创建request对象的Rule对象
request
request作为一个代理对象,其指向的是当前的请求的请求上下文RequestContext对象的request属性,即在请求上下文初始化的时候创建的请求对象,它是程序处理逻辑频繁需要的对象,存储着几乎所有的请求数据信息,本质上是Request对象。生命周期为一次请求期间,当请求处理完成后被销毁;
class Request(RequestBase):
url_rule = None # 记录本次请求的Rule对象
view_args = None # 本次请求的参数,指的是用路由转化器得到的参数
routing_exception = None # 如果路由匹配失败,记录错误对象
# 重要的属性
request.max_content_length # 获取该请求允许的数据包最大字节数
request.endpoint # 获取该请求的rule的标识符
request.url_charset # 获取url的编码
request.blueprint # 请求属于的蓝图
# 和路由相关的属性
print(request.url_root)
print(request.url)
print(request.url_rule)
print(request.host_url)
print(request.base_url)
print(request.path) # 路由路径,如/time
print(request.full_path) # 全路径,包括参数
print(request.script_root)
print(request.host) # 服务器的ip
print(request.access_route) # 所有转发的ip地址列表
print(request.remote_addr) # 客户端远程地址
# 结果
http://192.168.1.112:8000/
http://192.168.1.112:8000/time/time?a=1
/time/time
http://192.168.1.112:8000/
http://192.168.1.112:8000/time/time
# 获取请求数据
print(request.is_json) # 判断请求数据是否是json格式
print(request.get_json()) # 获取json数据
print(request.args) # 获取url中的参数作为字典返回,没有返回空对象
print(request.form) # 获取表单数据
print(request.values) # 同时获取表单数据和url参数
print(request.data) # 没有被其他格式解析成功的数据
print(request.files) # 获取上传的文件
print(request.cookies) # 获取cookie
print(request.headers) # 获取头部信息
session
session代理的是请求上下文RequestContext对象的session属性,其是在请求上下文被推送到栈的时候创建的session对象,类似一个字典的容器。每次请求创建的session实例都是新的,随着请求上下文被销毁而销毁。
关于flask的session实现机制和运用参考: flask基础之session机制详解
应用上下文AppContext
应用上下文对象AppContext会在必要时被创建和销毁,它不会在线程间移动,并且也不会在不同的请求之间共享;因此它可以作为在一次请求中临时存放数据的地方,其主要管理本次请求的当前应用app对象和临时全局g对象。
current_app = LocalProxy(_find_app)
g = LocalProxy(partial(_lookup_app_object, 'g'))
AppContext分析
flask的应用上下文可以主动创建,在不需要发生http请求的情况下;当请求上下文被推送到栈后,该请求的应用上下文会跟着创建加入栈中。
class AppContext(object):
def __init__(self, app):
self.app = app
self.url_adapter = app.create_url_adapter(None)
self.g = app.app_ctx_globals_class() # app的全局变量
current_app
current_app代理的就是当前的应用,我们可以在业务处理的任何时候通过current_app获取应用app的任何属性,之所以要这样做是为了避免app对象被到处显性传递造成循环导入的错误。current_app存在于应用上下文活跃期间,会在请求处理完成后,随着应用上下文销毁而销毁
from flask import current_app
app = Flask(__name__)
with app.app_context():
current_app.url_map
current_app必须在应用上下文被创建并且被推送后才能使用。
g
g一般的用法是在请求期间管理资源,其指向的是当前应用的app_ctx_globals_class属性,是一个_AppCtxGlobals对象;g对象是随着应用上下文生存或死亡。
class _AppCtxGlobals(object):
# 从g中获取数据
def get(self, name, default=None):
pass
# 获取数据并且弹出
def pop(self, name, default=_sentinel):
pass
# 在g中添加键值对,如果存在则忽略
def setdefault(self, name, default=None):
pass
我们可以将g对象看做dict的数据结构,它支持g.ab方式获取值和赋值。
with app.app_context():
g.ab = 'name' # 将{‘ab’:'name'}键值对添加到g中
x = g.ab # 获取ab的值,如果没有会报错,所以推荐使用g.get('ab')方法
总结
请求上下文面向开发者使用的对象主要是request和session;
应用上下文面向开发者使用的对象主要是current_app和g;
一次请求期间,请求上下文创建后会创建对应的本次请求的应用上下文;
请求上下文一般不可以单独存在,因为创建请求上下文需要请求数据作为参数;但是应用上下文可以单独存在并且可以手动推送;
参考
flask基础之AppContext应用上下文和RequestContext请求上下文(六)的更多相关文章
- flask 源码专题(二):请求上下文与全文上下文
源码解析 0. 请求入口 if __name__ == '__main__': app.run() def run(self, host=None, port=None, debug=None, lo ...
- flask基础之请求处理核心机制(五)
前言 总结一下flask框架的请求处理流程. 系列文章 flask基础之安装和使用入门(一) flask基础之jijia2模板使用基础(二) flask基础之jijia2模板语言进阶(三) flask ...
- flask 源码专题(三):请求上下文和应用上下文入栈与出栈
1.请求上下文和应用上下文入栈 # 将ctx入栈,但是内部也将应用上下文入栈 ctx.push() def push(self): # 获取到的 top == ctx top = _request_c ...
- Flask基础(12)-->请求上下文和应用上下文
请求上下文和应用上下文 请求上下文:可以简单理解为客户端与服务器之间数据交互请求的容器 请求上下文对象有:request.Session request:封装了HTTP请求的内容,针对的是http的请 ...
- Flask基础全套
Flask简介 Flask是主流PythonWeb三大框架之一,其特点是短小精悍以及功能强大从而获得众多Pythoner的追捧,相比于Django它更加简单更易上手,Flask拥有非常强大的三方库,提 ...
- flask基础之app初始化(四)
前言 flask的核心对象是Flask,它定义了flask框架对于http请求的整个处理逻辑.随着服务器被启动,app被创建并初始化,那么具体的过程是这样的呢? 系列文章 flask基础之安装和使用入 ...
- flask基础之session原理详解(十)
前言 flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活 ...
- flask基础之jijia2模板语言进阶(三)
前言 前面学习了jijia2模板语言的一些基础知识,接下来继续深挖jijia2语言的用法. 系列文章 flask基础之安装和使用入门(一) flask基础之jijia2模板使用基础(二) 控制语句 和 ...
- flask基础之jijia2模板使用基础(二)
前言 在以前前后端不分离的时代,后台程序员往往又当爹又当妈,需要将前端程序员写的h5页面填充模板语言.而jijia2是一门十分强大的python的模板语言,是flask框架的核心模块之一.先简单介绍一 ...
随机推荐
- 对HashMap的理解(二):高并发下的HashMap
在分析hashmap高并发场景之前,我们要先搞清楚ReHash这个概念.ReHash是HashMap在扩容时的一个步骤.HashMap的容量是有限的.当经过多次元素插入,使得HashMap达到一定饱和 ...
- JAXB java类与xml互转
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向 ...
- hbase 原子操作cas
在高并发的情况下,对数据row1 column=cf1:qual1, timestamp=1, value=val1的插入或者更新可能会导致非预期的情况, 例如:原本客户端A需要在value=val ...
- [洛谷P5081]Tweetuzki 爱取球
题目大意:有$n$个球,每一次取一个球然后放回,问期望多少次取遍所有球 题解:令$f_i$表示已经取了$i$种球,还要取的次数的期望.$f_i=\dfrac in(f_i+1)+\dfrac{n-i} ...
- 洛谷 P1270 “访问”美术馆 解题报告
P1270 "访问"美术馆 题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向 ...
- 项目管理---git----遇到问题------.gitignore不起作用
情况 在管理一个版本库时,有时候不想要管理某些文件,这个时候我就把这个问价写到.gitignore文件中,这样应该就可以将这个文件忽略,不再进行·版本管理了,但是经常出现的情况是:将这些文件名写到其中 ...
- 【THUSC2017】座位
题目背景 班级聚会的时候,班主任为了方便管理,规定吃饭的时候同一个寝室的同学必须坐在一起;但是吃完饭后,到了娱乐时间,喜欢不同游戏的同学会聚到一起;在这个过程中就涉及到了座位分配的问题. 题目描述 有 ...
- [POI2012]STU-Well
题意翻译 给定一个非负整数序列A,每次操作可以选择一个数然后减掉1,要求进行不超过m次操作使得存在一个Ak=0且max(∣xi−xi−1∣)最小,输出这个最小值以及此时最小的k (1≤n≤1 000 ...
- 《剑指offer》— JavaScript(16)合并两个排序的链表
合并两个排序的链表 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. *** 思路 如果pHead1和pHead2中有一个为空,则result是另 ...
- UESTC--1468
题目:A Coin Problem 原题链接:http://acm.uestc.edu.cn/problem.php?pid=1468 分析:满足裴波纳契数列,打表找周期. #include<i ...