zoukankan      html  css  js  c++  java
  • Local与LocalStack

    示例

    #flask源码中Local对象
    import functools
    try:
        from greenlet import getcurrent as get_ident
    except:
        from threading import get_ident
    
    #作用:为每个线程开辟空间
    class Local(object):
        __slots__ = ('__storage__', '__ident_func__')
    
        def __init__(self):
            # __storage__ = {1231:{'stack':[]}}
            object.__setattr__(self, '__storage__', {})
            object.__setattr__(self, '__ident_func__', get_ident)
    
        def __getattr__(self, name):
            try:
                return self.__storage__[self.__ident_func__()][name]
            except KeyError:
                raise AttributeError(name)
    
        def __setattr__(self, name, value):
            # name=stack
            # value=[]
            ident = self.__ident_func__()
            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)
    
    
    """
    __storage__ = {
        12312: {stack:[ctx(session/request) ,]}
    }
    
    """
    
    # obj = Local()
    # obj.stack = []
    # obj.stack.append('佳俊')
    # obj.stack.append('咸鱼')
    # print(obj.stack)
    # print(obj.stack.pop())
    # print(obj.stack)
    
    
    
    #作用:方便我们把Local中的列表维护成栈
    class LocalStack(object):
        def __init__(self):
            self._local = Local()
    
        def push(self,value):
            rv = getattr(self._local, 'stack', None) # self._local.stack =>local.getattr
            if rv is None:
                self._local.stack = rv = [] #  self._local.stack =>local.setattr
            rv.append(value) # self._local.stack.append(666)
            return rv
    
    
        def pop(self):
            """Removes the topmost item from the stack, will return the
            old value or `None` if the stack was already empty.
            """
            stack = getattr(self._local, 'stack', None)
            if stack is None:
                return None
            elif len(stack) == 1:
                return stack[-1]
            else:
                return stack.pop()
    
        def top(self):
            try:
                return self._local.stack[-1]
            except (AttributeError, IndexError):
                return None
    
    
    xxx = LocalStack()
    xxx.push('佳俊')
    xxx.push('咸鱼')
    
    
    #以上综合应用
    class RequestContext(object):
        def __init__(self):
            self.request = "xx"
            self.session = 'oo'
    
    _request_ctx_stack = LocalStack()
    
    _request_ctx_stack.push(RequestContext())
    
    
    def _lookup_req_object(arg):
    
        ctx = _request_ctx_stack.top()
    
        return getattr(ctx,arg) # ctx.request / ctx.session
    
    request = functools.partial(_lookup_req_object,'request')
    session = functools.partial(_lookup_req_object,'session')
    
    
    print(request())
    print(session())
    
    '''
        xx
        oo
    '''
  • 相关阅读:
    饿了么P7级前端工程师进入大厂的面试经验
    前端程序员面试的坑,简历写上这一条信息会被虐死!
    这次来分享前端的九条bug吧
    移动端开发必会出现的问题和解决方案
    创建一个dynamics 365 CRM online plugin (八)
    创建一个dynamics 365 CRM online plugin (七)
    创建一个dynamics 365 CRM online plugin (六)
    创建一个dynamics 365 CRM online plugin (五)
    使用User Primary Email作为GUID的问题
    怎样Debug Dynamics 365 CRM Plugin
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/13234565.html
Copyright © 2011-2022 走看看