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. Seafile的配置

    如果部署在apache或nginx后面,就是访问默认80或443.反向代理会帮你转到8000和8082上. 我使用443,我在路由器上设定了转发,比如 对外网12323这个端口会转到内网地址443上 ...

  2. (二)log4j 配置详解

    原文链接:https://blog.csdn.net/liupeifeng3514/article/details/79625013 1.配置根logger log4j.rootLogger = de ...

  3. 如何开发一个自己的npm包

    目录 一.初始化npm包 二.新建自己的工具类 三.新建入口文件index.js 四.编写单元测试 五.登录仓库 六.发布包 七.安装使用 八.删除包 一.初始化npm包 npm init 运行输入包 ...

  4. startActivityForResult调用另外一个Activity获取返回结果

    startActivityForResult(intent,requestCode)可以调用另外一个Activity,并返回结果. 换头像案例 activity_main.xml <?xml v ...

  5. 关于单向循环链表的约瑟夫问题(Java实现)

    关于单向循环链表的约瑟夫问题(Java实现) 最近在学习链表时,遇到单向循环链表中的约瑟夫问题.在构建循环链表的代码上,我有一点很不理解,遂记录下来. Josephu问题为: 设编号为1, 2,.. ...

  6. [搬运]Intellij IDEA 汉化

    Github地址: https://github.com/pingfangx/TranslatorX

  7. 【K8s学习笔记】K8s是如何部署应用的?

    本文内容 本文致力于介绍K8s一些基础概念与串联部署应用的主体流程,使用Minikube实操 基础架构概念回顾 温故而知新,上一节[K8S学习笔记]初识K8S 及架构组件 我们学习了K8s的发展历史. ...

  8. redis编译报错总结

    redis编译报错总结: 1.不能编译没有GCC 编译工具安装报错:问题1:make时可能会报如下错误cc -c -std=c99 -pedantic -O2 -Wall -W   -g -rdyna ...

  9. 02 [掌握] redis详情命令

    1,常用命令 keys * 获取所有的key select 0 选择第一个库 move myString 1 将当前的数据库key移动到某个数据库,目标库有,则不能移动 flushdb 清除指定库 r ...

  10. 并发07--线程池及Executor框架

    一.JAVA中的线程池 线程池的实现原理及流程如下图所示: 如上图所示,当一个线程提交到线程池时(execute()或submit()),先判断核心线程数(corePoolSize)是否已满,如果未满 ...