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

时间:2019-11-25 20:53:35   收藏:0   阅读:83

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. 总结

技术分享图片

原文:https://www.cnblogs.com/liubing8/p/11930180.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!