04 LocalStack和Local对象实现栈的管理

1.源码入口

from flask import globals
# 从globals进入可以看见此源码

1. flask源码关于local的实现

  1. local与localstack关系

    • flask中是localstack结合local使用
    • local为localstack提供基本结构
  2. 源码实现

    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的实现

  1. 两个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),]},
    }
  2. 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对象实现栈的管理的更多相关文章

  1. 04 flask源码剖析之LocalStack和Local对象实现栈的管理

    04 LocalStack和Local对象实现栈的管理 目录 04 LocalStack和Local对象实现栈的管理 1.源码入口 1. flask源码关于local的实现 2. flask源码关于l ...

  2. LocalStack和Local对象实现栈的管理

    flask里面有两个重要的类Local和LocalStack 输入from flask import globals 左键+ctrl点globals进入源码,进去后找57行 flask只会实例化出这两 ...

  3. flask 源码专题(二):请求上下文与全文上下文

    源码解析 0. 请求入口 if __name__ == '__main__': app.run() def run(self, host=None, port=None, debug=None, lo ...

  4. flask 源码专题(五):SqlAlchemy 中操作数据库时session和scoped_session的区别

    1原生session: from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalc ...

  5. flask 源码专题(九):flask扩展点

    1. 信号(源码) 信号,是在flask框架中为我们预留的钩子,让我们可以进行一些自定义操作. pip3 install blinker 2. 根据flask项目的请求流程来进行设置扩展点 中间件 # ...

  6. flask 源码专题(一):app.run()的背后

    当我们用Flask写好一个app后, 运行app.run()表示监听指定的端口, 对收到的request运行app生成response并返回. 现在分析一下, 运行app.run()后具体发生了什么事 ...

  7. flask 源码专题(八):路由加载

    1.示例代码 from flask import Flask app = Flask(__name__,static_url_path='/xx') @app.route('/index') def ...

  8. flask 源码专题(六):session处理机制

    前言 flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活 ...

  9. flask 源码专题(三):请求上下文和应用上下文入栈与出栈

    1.请求上下文和应用上下文入栈 # 将ctx入栈,但是内部也将应用上下文入栈 ctx.push() def push(self): # 获取到的 top == ctx top = _request_c ...

随机推荐

  1. 防止暴力破解-DenyHosts应用

    当你的linux服务器暴露在互联网之中,该服务器将会遭到互联网上的扫描软件进行扫描,并试图猜测SSH登录口令.   你会发现,每天会有多条SSH登录失败纪录.那些扫描工具将对你的服务器构成威胁,你必须 ...

  2. 千万不要更新网易云音乐UWP!!!!!

    网易云音乐UWP没了!!! 现在 Micrsoft Store 里面的是垃圾 Win32 转置版!!!! 万不可更新!!! 若已经更新,还有救回来的办法:下载 https://lanzous.com/ ...

  3. 《ElasticSearch入门》一篇管够,持续更新

    一.顾名思义: Elastic:灵活的:Search:搜索引擎 二.官方简介: Elasticsearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTf ...

  4. NAT网络地址转化和DHCP

    DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)通常被应用在大型的局域网络环境中,主要作用是集中的管理.分配IP地址,使网络环境中的主机动态的获得I ...

  5. cb01a_c++_数据结构_顺序容器_STL_deque类

    /*cb01a_c++_数据结构_顺序容器_STL_deque类deque是一个动态数组,比vector更加灵活.两者都属于动态数组deque与vector非常类似deque可以在数组开头和末尾插入和 ...

  6. ca77a_c++__一个打开并检查文件输入的程序_流对象_操作文件

    /*ca77a_c++__一个打开并检查文件输入的程序 习题:8.13 8.14*/ /*ca77a_c++__一个打开并检查文件输入的程序 习题:8.13 8.14 */ #include < ...

  7. nginx在windows系统中启动、重启、停止,常用命令

    cmd终端在进入到nginx的安装目录下使用对应命令 查看nginx的版本号:nginx -v 启动nginx:start nginx 快速停止或关闭nginx:nginx -s stop 正常停止或 ...

  8. Spring如何解决循环依赖?

    介绍 先说一下什么是循环依赖,Spring在初始化A的时候需要注入B,而初始化B的时候需要注入A,在Spring启动后这2个Bean都要被初始化完成 Spring的循环依赖有两种场景 构造器的循环依赖 ...

  9. Java容器:HashMap连环炮

    本文来源于:https://mp.weixin.qq.com/s/oRx-8XXbgage9Hf97WrDQQ, 公众号:安琪拉的博客 前言 HashMap应该算是Java后端工程师面试的必问题,因为 ...

  10. 35 _ 队列1 _ 什么是队列.swf

    队列是一种可以实现一个先进先出的存储结构 什么是队列? 队列(Queue)也是一种运算受限的线性表.它只允许在表的一端进行插入,而在另一端进行删除.允许删除的一端称为队头(front),允许插入的一端 ...