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 ...
随机推荐
- 一台电脑如何使用多个git账号?
git相信大家都在用,一般公司有一个账号,放公司自己架的服务器中,员工自己还有一个github或者gitee的账号,存放自己的一些私有代码.本篇文章总结一下,本人在公司开发机上,使用多个git账号的干 ...
- 关于"touchstart与click同时触发"问题
点击事件可以分解成多个事件: 在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend --> click 由于移动设备能够同时 ...
- 纯 HTML/CSS 高仿 Win10 加载动画
自己做的超高仿Win10加载动画(应该是全网最像的 HTML 实现了),自己想用就拿去用吧 转圈加载 在线演示 HTML: <div class="loading"> ...
- python第三方库大全
环境管理 管理 Python 版本和环境的工具 p:非常简单的交互式 python 版本管理工具.官网 pyenv:简单的 Python 版本管理工具.官网 Vex:可以在虚拟环境中执行命令.官网 v ...
- java中工厂模式
最近在项目中使用了工厂模式来重构下之前的代码,在这里做个小结. 工厂模式最主要的特点是每次新增一个产品的时候,都需要新增一个新的工厂,这样在对于新的产品做扩展的时候,减少对客户端代码的修改. 我在项目 ...
- 基于docker-compose搭建gitlab
安装及配置 修改docker-compose文件 vim docker-compose.yml gitlab: image: 'gitlab/gitlab-ce:latest' restart: al ...
- SpringCloud 入门(二)
前文我们介绍了创建注册中心的过程以及配置,接下来我们再简单的创建一个客户端 基本操作和前文一样,不一样的是选择的依赖 然后下一步,修改启动类和配置,结构如下图 修改配置文件application-te ...
- 微服务配置中心 Apollo 源码解析——Admin 发送发布消息
内容参考:https://www.toutiao.com/a6643383570985386509/ 摘要: 原创出处http://www.iocoder.cn/Apollo/admin-server ...
- Downloadmanager实现app实现的升级下载使用
1.app升级下载现在不推荐使用downloadmanager下载: 原因有下面的几个方面: (1)三星note系列部分手机需要手动打开这个权限才能用这个功能,而有些国产手机更加nb了直接个阉割了(d ...
- 恕我直言你可能真的不会java第8篇-函数式接口
一.函数式接口是什么? 所谓的函数式接口,实际上就是接口里面只能有一个抽象方法的接口.我们上一节用到的Comparator接口就是一个典型的函数式接口,它只有一个抽象方法compare. 只有一个抽象 ...