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 ...
随机推荐
- redis5.0.7集群搭建
这里实验的是129.130.240三台服务器6个节点的部署(redis集群最低要6个节点,不然无法创建). 1.压缩包安装 #wget http://download.redis.io/release ...
- cb27a_c++_STL_算法_最小值和最大值
cb27a_c++_STL_算法_最小值和最大值min_element(b,e) b--begin(), e--end()min_element(b,e,op). op:函数,函数对象,一元谓词.ma ...
- cron计划任务
格式 crontab -e [-u 用户名] ##编辑:注意,每项工作都是一行. crontab -l [-u 用户名] ##查看 crontab -r [-u 用户名] #清除 分 时 日 月 周 ...
- logback.xml 不能被加载,logback不能被执行,logback.xml 无法生效,slf4j日志样式输出失败
1. 原因 logback.xml 无法被加载, 尝试了好久还是失败,哎,最后新建工程竟然可以,所以说还是项目的问题: 原来项目依赖了两个slf4j.jar,是版本冲突了: 2. 查找原因 idea ...
- springboot 集成mybatis时日志输出
application.properties(yml)中配置的两种方式: 这两种方式的效果是一样的,但是下面一种可以指定某个包下的SQL打印出来,上面这个会全部的都会打印出来.
- 补充:回答网友的问题,如何不用路径,而直接将CImage画到DC中,之后DC一起显示.
补充:回答网友的问题,如何不用路径,而直接将CImage画到DC中,之后DC一起显示.注释掉 pDC->BeginPath(); // 打开路径层 pDC->Rectangle(0,0,p ...
- Nginx 反向代理可以缓存 HTTP POST 请求页面吗?
摘要: Nginx 反向代理可以缓存 HTTP POST 请求页面吗? 2017-09-05 景峯 Netkiller 本文节选自<Netkiller Web 手札> 作者:netkil ...
- Java中栈和堆讲解
之前对JVM中堆内存和栈内存都是一直半解,今天有空就好好整理一下,用作学习笔记. 包括Java程序在内,任何程序在运行时都是要开辟内存空间的.JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区 ...
- 全宇宙首本 VS Code 中文书,来了!
大家好!我是韩骏,VS Code 中文社区创始人,VS Code 的代码贡献者.2013 年,毕业于上海交通大学软件学院,现在是微软开发平台事业部的软件工程师.写过 20 多款 VS Code 插件, ...
- Nginx平滑升级详细步骤-113p.cn
认识平滑升级 有时候我们需要对Nginx版本进行升级以满足运维人员对其功能的需求,例如添加xxx模块,需要xxx功能,而此时Nginx又在跑着业务无法停掉,这时我们就只能平滑升级了. 平滑升级原理 N ...