flask 源码专题(十一):LocalStack和Local对象实现栈的管理
04 LocalStack和Local对象实现栈的管理
1.源码入口
from flask import globals
# 从globals进入可以看见此源码
1. flask源码关于local的实现
local与localstack关系
- flask中是localstack结合local使用
- local为localstack提供基本结构
源码实现
try:
# 协程
from greenlet import getcurrent as get_ident
except ImportError:
try:
from thread import get_ident
except ImportError:
from _thread import get_ident
"""
__storage__ = {
1111:{"stack":[张三] }
}
"""
class Local(object): def __init__(self):
# self.__storage__ = {}
# self.__ident_func__ = get_ident
object.__setattr__(self, "__storage__", {})
object.__setattr__(self, "__ident_func__", get_ident) def __iter__(self):
return iter(self.__storage__.items()) def __release_local__(self):
self.__storage__.pop(self.__ident_func__(), None) def __getattr__(self, name):
try:
return self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name) def __setattr__(self, name, value):
ident = self.__ident_func__() # 1111
storage = self.__storage__
try:
storage[ident][name] = value
except KeyError:
storage[ident] = {name: value} def __delattr__(self, name):
try:
del self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name)
2. flask源码关于localstack的实现
两个localstack对象
- 存储RequestContext相关,包括reqeust、session
- 存储AppContenxt相关,包括app、g(所有app对象都包括在里边)
_request_ctx_stack = LocalStack()
__storage__ = {
1111:{'stack':[RequestContext(reqeust,session),]},
1123:{'stack':[RequestContext(reqeust,session),]},
} _app_ctx_stack = LocalStack()
__storage__ = {
1111:{'stack':[AppContenxt(app,g),]}
1123:{'stack':[AppContenxt(app,g),]},
}localstack源码实现
class LocalStack(object):
def __init__(self):
self._local = Local()
def push(self, obj):
"""Pushes a new item to the stack"""
# self._local.stack == getattr
# rv = None
rv = getattr(self._local, "stack", None)
if rv is None:
self._local.stack = rv = []
rv.append(obj)
return rv def pop(self):
stack = getattr(self._local, "stack", None)
if stack is None:
return None
elif len(stack) == 1:
# release_local(self._local)
# del __storage__[1111]
return stack[-1]
else:
return stack.pop() @property
def top(self):
try:
return self._local.stack[-1]
except (AttributeError, IndexError):
return None obj = LocalStack()
obj.push('张三')
obj.push('李四') print(obj.top) obj.pop()
obj.pop()
3. 总结
在flask中有个local类,他和threading.local的功能一样,为每个线程开辟空间进行存取数据,他们两个的内部实现机制,内部维护一个字典,以线程(协程)ID为key,进行数据隔离,如:
__storage__ = {
1211:{'k1':123}
} obj = Local()
obj.k1 = 123在flask中还有一个LocalStack的类,他内部会依赖local对象,local对象负责存储数据,localstack对象用于将local中的值维护成一个栈。
__storage__ = {
1211:{'stack':['k1',]}
} obj= LocalStack()
obj.push('k1')
obj.top
obj.pop()flask上下文管理也是基于此
- 请求上下文管理
- 应用上下文管理
flask 源码专题(十一):LocalStack和Local对象实现栈的管理的更多相关文章
- 04 flask源码剖析之LocalStack和Local对象实现栈的管理
04 LocalStack和Local对象实现栈的管理 目录 04 LocalStack和Local对象实现栈的管理 1.源码入口 1. flask源码关于local的实现 2. flask源码关于l ...
- LocalStack和Local对象实现栈的管理
flask里面有两个重要的类Local和LocalStack 输入from flask import globals 左键+ctrl点globals进入源码,进去后找57行 flask只会实例化出这两 ...
- flask 源码专题(二):请求上下文与全文上下文
源码解析 0. 请求入口 if __name__ == '__main__': app.run() def run(self, host=None, port=None, debug=None, lo ...
- flask 源码专题(五):SqlAlchemy 中操作数据库时session和scoped_session的区别
1原生session: from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalc ...
- flask 源码专题(九):flask扩展点
1. 信号(源码) 信号,是在flask框架中为我们预留的钩子,让我们可以进行一些自定义操作. pip3 install blinker 2. 根据flask项目的请求流程来进行设置扩展点 中间件 # ...
- flask 源码专题(一):app.run()的背后
当我们用Flask写好一个app后, 运行app.run()表示监听指定的端口, 对收到的request运行app生成response并返回. 现在分析一下, 运行app.run()后具体发生了什么事 ...
- flask 源码专题(八):路由加载
1.示例代码 from flask import Flask app = Flask(__name__,static_url_path='/xx') @app.route('/index') def ...
- flask 源码专题(六):session处理机制
前言 flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活 ...
- flask 源码专题(三):请求上下文和应用上下文入栈与出栈
1.请求上下文和应用上下文入栈 # 将ctx入栈,但是内部也将应用上下文入栈 ctx.push() def push(self): # 获取到的 top == ctx top = _request_c ...
随机推荐
- 防止暴力破解-DenyHosts应用
当你的linux服务器暴露在互联网之中,该服务器将会遭到互联网上的扫描软件进行扫描,并试图猜测SSH登录口令. 你会发现,每天会有多条SSH登录失败纪录.那些扫描工具将对你的服务器构成威胁,你必须 ...
- 千万不要更新网易云音乐UWP!!!!!
网易云音乐UWP没了!!! 现在 Micrsoft Store 里面的是垃圾 Win32 转置版!!!! 万不可更新!!! 若已经更新,还有救回来的办法:下载 https://lanzous.com/ ...
- 《ElasticSearch入门》一篇管够,持续更新
一.顾名思义: Elastic:灵活的:Search:搜索引擎 二.官方简介: Elasticsearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTf ...
- NAT网络地址转化和DHCP
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)通常被应用在大型的局域网络环境中,主要作用是集中的管理.分配IP地址,使网络环境中的主机动态的获得I ...
- cb01a_c++_数据结构_顺序容器_STL_deque类
/*cb01a_c++_数据结构_顺序容器_STL_deque类deque是一个动态数组,比vector更加灵活.两者都属于动态数组deque与vector非常类似deque可以在数组开头和末尾插入和 ...
- ca77a_c++__一个打开并检查文件输入的程序_流对象_操作文件
/*ca77a_c++__一个打开并检查文件输入的程序 习题:8.13 8.14*/ /*ca77a_c++__一个打开并检查文件输入的程序 习题:8.13 8.14 */ #include < ...
- nginx在windows系统中启动、重启、停止,常用命令
cmd终端在进入到nginx的安装目录下使用对应命令 查看nginx的版本号:nginx -v 启动nginx:start nginx 快速停止或关闭nginx:nginx -s stop 正常停止或 ...
- Spring如何解决循环依赖?
介绍 先说一下什么是循环依赖,Spring在初始化A的时候需要注入B,而初始化B的时候需要注入A,在Spring启动后这2个Bean都要被初始化完成 Spring的循环依赖有两种场景 构造器的循环依赖 ...
- Java容器:HashMap连环炮
本文来源于:https://mp.weixin.qq.com/s/oRx-8XXbgage9Hf97WrDQQ, 公众号:安琪拉的博客 前言 HashMap应该算是Java后端工程师面试的必问题,因为 ...
- 35 _ 队列1 _ 什么是队列.swf
队列是一种可以实现一个先进先出的存储结构 什么是队列? 队列(Queue)也是一种运算受限的线性表.它只允许在表的一端进行插入,而在另一端进行删除.允许删除的一端称为队头(front),允许插入的一端 ...