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上下文管理也是基于此
- 请求上下文管理
- 应用上下文管理
本文来自博客园,作者:秋华,转载请注明原文链接:https://www.cnblogs.com/qiu-hua/p/12485620.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通