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. Apache(httpd)详解

    httpd详解(思维导图) 1. httpd服务 ASF 服务器类型 http服务器 应用程序服务器 httpd的特性 高度模块化 DSO机制 MPM httpd的并发响应模型 prefork wor ...

  2. 用turtle画蛇

    import turtle def drawSnake(rad,angle,len,nackrad): for i in range(len): turtle.circle(rad,angle) #画 ...

  3. 东方步进电机马达驱动板CVK系列说明书

    东方步进电机马达驱动板CVK系列说明书

  4. cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法

    //*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...

  5. 001.OpenShift介绍

    一 OpenShift特性 1.1 OpenShift概述 Red Hat OpenShijft Container Platform (OpenShift)是一个容器应用程序平台,它为开发人员和IT ...

  6. GeckoDriver+Selenium+Python的安装和使用

    如果没有安装GeckoDriver会提示: selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executab ...

  7. js中each函数的用法

    官方说明: jQuery.each(object, [callback]) 概述 通用例遍方法,可用于例遍对象和数组. 不同于例遍 jQuery 对象的 $().each() 方法,此方法可用于例遍任 ...

  8. Apache Hudi:云数据湖解决方案

    1. 引入 开源Apache Hudi项目为Uber等大型组织提供流处理能力,每天可处理数据湖上的数十亿条记录. 随着世界各地的组织采用该技术,Apache开源数据湖项目已经日渐成熟. Apache ...

  9. C#多线程编程(一)进程与线程

    一. 进程 简单来说,进程是对资源的抽象,是资源的容器,在传统操作系统中,进程是资源分配的基本单位,而且是执行的基本单位,进程支持并发执行,因为每个进程有独立的数据,独立的堆栈空间.一个程序想要并发执 ...

  10. easymock笔记2

    EasyMock主要是为测试提供模拟数据,比如你可以模拟HttpServletRequest. EasyMock 可以mock interface和抽象java 类,但是不可以mock拥有被final ...