flask中Local源码数据类型
首先明确:
源码中要构造的数据类型数是这样的:
__storage__ = {
用线程或者协程的唯一标识为键: {stack:[ctx(session/request) ,]}
}
其次源码用Local类构造数据类型,然后又用LocalStack类,作用是操作Local,让我们使用起来更方便,
LocalStack类中封装了push方法,用来给调用Local添加数据,pop方法取数据,

下面来看看具体代码怎么实现的
Local类构造数据类型
#用线程或者协程的唯一标识为键,
try:
# 协程唯一标识
from greenlet import getcurrent as get_ident
except:
# 进程唯一标识
from threading import get_ident class Local(object):
# __slots__设置只允许调用的属性
__slots__ = ('__storage__', '__ident_func__') def __init__(self):
# __storage__ = {1231:{'stack':[]}}
object.__setattr__(self, '__storage__', {}) #__storage__={}
object.__setattr__(self, '__ident_func__', get_ident) #__ident_func__= get_ident
#取数据
def __getattr__(self, name):
try:
return self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name)
#主要的数据构造过程
def __setattr__(self, name, value):
# name=stack
# value=[]
#self对象调用属性
ident = self.__ident_func__() #get_ident()
storage = self.__storage__ #storage={}
try:
storage[ident][name] = value #storage={get_ident():{stack:[]}}
except KeyError:
storage[ident] = {name: value}
#删除数据
def __delattr__(self, name):
try:
del self.__storage__[self.__ident_func__()][name]
except KeyError:
raise AttributeError(name) #调用测试
obj = Local()
obj.stack = []
obj.stack.append('胖虎')
obj.stack.append('咸鱼')
print(obj.stack)
print(obj.stack.pop())
print(obj.stack)
"""
数据构造结果:
__storage__ = {
12312: {stack:[]}
} """
LocalStack类操作Local
# LocalStack 操作Local的类,让我们用起来更方法
class LocalStack(object):
def __init__(self):
# 以Local对象作为属性
self._local = Local()
# 向Local放值
def push(self,value):
# 会先执行Local类里面的__setattr__(self, name, value)方法,存储数据
rv = getattr(self._local, 'stack', None) # self._local.stack =>local.getattr
if rv is None:
self._local.stack = rv = [] # self._local.stack =>local.setattr
rv.append(value) # self._local.stack.append(666)
return rv #调用local取数据
def pop(self):
"""Removes the topmost item from the stack, will return the
old value or `None` if the stack was already empty.
"""
stack = getattr(self._local, 'stack', None)
if stack is None:
return None
elif len(stack) == 1:
return stack[-1]
else:
return stack.pop()
#
def top(self):
try:
return self._local.stack[-1]
except (AttributeError, IndexError):
return None
最终实例化LocalStack类为_request_ctx_stack
通过_request_ctx_stack对象来操作Local,然后把ctx.request / ctx.session放到Local数据类型中
#实例化
_request_ctx_stack = LocalStack() _request_ctx_stack.push(RequestContext()) def _lookup_req_object(arg): ctx = _request_ctx_stack.top() return getattr(ctx,arg) # ctx.request / ctx.session #把request和session都封装到了Local中
request = functools.partial(_lookup_req_object,'request')
session = functools.partial(_lookup_req_object,'session')
												

flask-Local源码流程解析的更多相关文章

  1. Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析

    一.一个请求来到Django 的生命周期   FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...

  2. Rest Framework源码流程解析

    目录: 一 整体流程 二 具体流程 一 请求进来之后,都要先执行dispatch方法,dispatch方法根据请求方式的不同触发get/post/put/delete等方法 注意,APIView中的d ...

  3. Flask信号源码流程

    1. appcontext_pushed = _signals.signal('appcontext-pushed'# 请求app上下文push时执行 return RequestContext(se ...

  4. rest_framework解析器组件源码流程

    rest_framework解析器组件源码流程 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数 ...

  5. Flask源码流程分析(一)

    Flask源码流程分析: 1.项目启动: 1.实例化Flask对象 1. 重要的加载项: * url_rule_class = Rule * url_map_class = Map * session ...

  6. Flask 源码流程,上下文管理

    源码流程 创建对象 from flask import Flask """ 1 实例化对象 app """ app = Flask(__na ...

  7. mybatis 3.x源码深度解析与最佳实践(最完整原创)

    mybatis 3.x源码深度解析与最佳实践 1 环境准备 1.1 mybatis介绍以及框架源码的学习目标 1.2 本系列源码解析的方式 1.3 环境搭建 1.4 从Hello World开始 2 ...

  8. ES6.3.2 index操作源码流程

    ES 6.3.2 index 操作源码流程 client 发送请求 TransportBulkAction#doExecute(Task,BulkRequest,listener) 解析请求,是否要自 ...

  9. Go netpoll I/O 多路复用构建原生网络模型之源码深度解析

    导言 Go 基于 I/O multiplexing 和 goroutine 构建了一个简洁而高性能的原生网络模型(基于 Go 的I/O 多路复用 netpoll),提供了 goroutine-per- ...

随机推荐

  1. ASP.NET CORE-Info:TechEmpower最新一轮的性能测试出炉,ASP.NET Core依旧表现不俗

    ylbtech-ASP.NET CORE-Info:TechEmpower最新一轮的性能测试出炉,ASP.NET Core依旧表现不俗 1.返回顶部 1. TechEmpower在10月30发布最新一 ...

  2. CSS:CSS 字体

    ylbtech-CSS:CSS 字体 1.返回顶部 1. CSS 字体 CSS字体属性定义字体,加粗,大小,文字样式. serif和sans-serif字体之间的区别  在计算机屏幕上,sans-se ...

  3. try-with-resources 让java资源关闭代码更简洁

    一.JDK7的资源关闭方式优化 1 try-with-resource语法 在JDK7以前,Java没有自动关闭外部资源的语法特性,直到JDK7中新增了try-with-resource语法,才实现了 ...

  4. Invoking destroy method 'close' on bean with name 'dataSource'

    Invoking destroy method 'close' on bean with name 'dataSource' Spring与Mybatis整合时出现的问题,找了一晚上结果是一个属性写错 ...

  5. Netty 源码学习——服务端流程分析

    在上一篇我们已经介绍了客户端的流程分析,我们已经对启动已经大体上有了一定的认识,现在我们继续看对服务端的流程来看一看到底有什么区别. 服务端代码 public class NioServer { pr ...

  6. Gradle任务

    Gradle构建脚本描述一个或多个项目.每个项目都由不同的任务组成.任务是构建执行的一项工作.任务可以是编译一些类,将类文件存储到单独的目标文件夹中,创建JAR,生成Javadoc或将一些归档发布到存 ...

  7. 2019-8-31-dotnet-通过-HttpClient-下载文件同时报告进度的方法

    title author date CreateTime categories dotnet 通过 HttpClient 下载文件同时报告进度的方法 lindexi 2019-08-31 16:55: ...

  8. Jenkins添加Windows自动化构建方案

    一.为Jenkins添加Windows节点 这里需要填写远程工作目录,启动方法一项一定要选择"Launch agent via Java Web Start"一项,其它的保持默认. ...

  9. Mysql流程解析

    Mysql流程解析 流程图 流程图解析 客户端发送一条sql语句. 1.此时,mysql会检查sql语句,查看是否命中缓存,如果命中缓存,直接返回结果,不继续执行.没有命中则进入解析器. 2.解析器会 ...

  10. Dart编程字符串

    String数据类型表示一系列字符.Dart字符串是一系列UTF 16代码单元. Dart中的字符串值可以使用 单引号 或 双引号 或 三引号 表示.单行字符串使用单引号或双引号表示.三引号用于表示多 ...