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')
												

最新文章

  1. mac brew mysql 启动之后报错
  2. Android 学习笔记之AndBase框架学习(一) 实现多功能标题栏
  3. Android--下拉框
  4. Linux 下 apache 日志分析与状态查看[转]
  5. [转载]ubuntu的版本
  6. static用法总结
  7. hdu 4579 Random Walk 概率DP
  8. zookeeper使用场景【转】
  9. HDOJ 1423 Greatest Common Increasing Subsequence -- 动态规划
  10. [2017-08-25]100行CSharp代码利用dynamic写个DSL(特定领域语言)
  11. SQL 一列数据整合为一条数据
  12. JavaSE学习(二):进制转换—数据类型转换—Java运算符
  13. nginx 中配置多个location并解决js/css/jpg/等的加载问题
  14. QQ去除未读状态的动画
  15. open-falcon之agent
  16. URL的应用
  17. TSQL--NULL值和三值逻辑
  18. 最新zencart支付宝插件(支持1.5)
  19. mac下mysql5.7.18修改root密码
  20. 北京Uber优步司机奖励政策(11月16日~11月22日)

热门文章

  1. 搭建hadoop集群 单机版
  2. linux:lrzsz安装
  3. Django框架(四)—— 路由控制:有名/无名分组、反向解析、路由分发、名称空间、伪静态、APPEND_SLASH、不同版本的Django区别
  4. linux内核编译时如何根据spec指定编译包
  5. Ubuntu终端内打开文件管理器
  6. Spring IOC源码分析(二):Bean工厂体系结构设计
  7. P3224 [HNOI2012]永无乡(平衡树合并)
  8. sqlldr details
  9. word embedding 精要整理
  10. vue之axios的使用