from flask import globals
# 从globals进入可以看见此源码
local与localstack关系
源码实现
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)
两个localstack对象
_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),]},
}
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()
在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对象实现栈的管理
原文:https://www.cnblogs.com/qiu-hua/p/12485620.html