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上下文管理也是基于此

    • 请求上下文管理
    • 应用上下文管理

04 flask源码剖析之LocalStack和Local对象实现栈的管理的更多相关文章

  1. flask 源码专题(十一):LocalStack和Local对象实现栈的管理

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

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

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

  3. flask源码剖析系列(系列目录)

    flask源码剖析系列(系列目录) 01 flask源码剖析之werkzurg 了解wsgi 02 flask源码剖析之flask快速使用 03 flask源码剖析之threading.local和高 ...

  4. 04 drf源码剖析之版本

    04 drf源码剖析之版本 目录 04 drf源码剖析之版本 1. 版本简述 2. 版本使用 3.源码剖析 4. 总结 1. 版本简述 API版本控制使您可以更改不同客户端之间的行为.REST框架提供 ...

  5. 08 Flask源码剖析之flask拓展点

    08 Flask源码剖析之flask拓展点 1. 信号(源码) 信号,是在flask框架中为我们预留的钩子,让我们可以进行一些自定义操作. pip3 install blinker 2. 根据flas ...

  6. Flask源码剖析详解

    1. 前言 本文将基于flask 0.1版本(git checkout 8605cc3)来分析flask的实现,试图理清flask中的一些概念,加深读者对flask的理解,提高对flask的认识.从而 ...

  7. 07 flask源码剖析之用户请求过来流程

    07 Flask源码之:用户请求过来流程 目录 07 Flask源码之:用户请求过来流程 1.创建ctx = RequestContext对象 2. 创建app_ctx = AppContext对象 ...

  8. flask 源码剖析

    flask 上下文管理源码流程及涉及的部分技术点 [flask源码梳理]之一  偏函数_mro [flask源码梳理]之二  面向对象中__setattr__ [flask源码梳理]之三  Local ...

  9. 05 flask源码剖析之配置加载

    05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...

随机推荐

  1. fopen函数中的mode参数

    fopen FILE * fopen ( const char * filename, const char * mode ); 其中,参数mode可取以下值: "r"read: ...

  2. MyISAM和InnoDB的差异

    转载:https://www.cnblogs.com/xc-chejj/p/11245034.html MyISAM是默认表类型,基于ISAM(Indexed Sequential Access Me ...

  3. Linux下常用命令(持续更新)

    l: 列举目录下的所有文件 ll: 显示详细属性 pwd: 查看当前所在完整路径 cd: 变更文件夹(变更到根目录:cd + /:变更到上级目录:cd + ..) sudo: 允许利用超级用户权限执行 ...

  4. 基于Web的监控系统的开发进行分布式和现代生产(外文翻译)

    摘要 近年来,Web技术发展迅速.尤其是网络浏览器增强了其功能因为JavaScript,CSS3和HTML5的改进.因此,功能越来越丰富的基于Web的软件解决方案功能范围可用.通过使用响应式网页设计( ...

  5. 获取系统的IP地址

    获取linux主机的IP地址 问题描述 在很多软件配置过程中,都需要设置ID信息,通常我选择使用系统配置的eth0网卡的IP地址信息,比如salt-minion-id,在通过cobbler批量安装操作 ...

  6. 甜咸粽子党大战,Python爬取淘宝上的粽子数据并进行分析

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 爬虫 爬取淘宝数据,本次采用的方法是:Selenium控制Chrome浏览 ...

  7. Java中的I/O流全汇总,所有的I/O就一张图

    放大再看,注意视力!哈哈   一口吃不成胖子,一点一点的看: 大家都是文化人,拿图要指明出处!!!  头上↑那框,对,就是那 使用的是XMind软件画的,要源文件吗? 在这里:https://gith ...

  8. Day10-微信小程序实战-交友小程序-实现删除好友信息与子父组件间通信

    回顾:上一次已经把消息的布局以及样式做好了 效果图: 在removeList.js文件中,messageId就是发起这个消息的用户了 先查看一下自定义组件的生命周期 https://developer ...

  9. 【原】二进制部署 k8s 1.18.3

    二进制部署 k8s 1.18.3 1.相关前置信息 1.1 版本信息 kube_version: v1.18.3 etcd_version: v3.4.9 flannel: v0.12.0 cored ...

  10. LQR算法如何跟随变化的期望状态

    开门见山,通过LQR的能量函数可以看出,LQR算法是将状态量控制到零(关于能量函数请看我的随笔:LQR要点),但实际控制中我们希望状态量能够跟随期望值 下面将会解决如何用LQR算法跟随变化的期望值: ...