• Werkzeug之LocalStack源码解析


    Werkzeug之LocalStack源码解析

    原博文地址

    http://liuyajing.coding.me/blogs/python/2018/werkzeug-localstack/
    

    一、引入

    最近在阅读 Flask 的源码,遇到三个概念:Local 、 LocalStack 和 LocalProxy ,本文主要就针对 LocalStack 概念及其源码进行原理剖析。
    

    二、原理

    这个类类似于:class:Local,但是在 storage[ident] 中存放的是一个 key 为 stack,value 为 一个堆列表的形式,例如:
    
    >>> ls = LocalStack()
    >>> ls.push(42)
    >>> ls.top
    42
    >>> ls.push(23)
    >>> ls.top
    23
    >>> ls.pop()
    23
    >>> ls.top
    42
    '''
    它们可以通过使用:class:LocalManager或使用:func:release_local函数强制释放,但正确的方法是在使用后从堆栈中弹出元素。 当堆栈为空时,它将不再绑定到当前上下文(并因此释放)。
    通过不带参数调用实例方法,它返回一个代理,该代理解析为堆栈中最顶层的元素。
    '''
    

    三、LocalStack

    1. init

    def __init__(self):
        self._local = Local()
    '''
    __init__方法生成了一个新的Local实例, 并赋值给了_local属性。
    '''
    

    2. release_local

    def __release_local__(self):
        self._local.__release_local__()
    '''
    此方法调用Local实例的__release_local__方法。
    '''
    

    3. get__ident_func_

    def _get__ident_func__(self):
        return self._local.__ident_func__
    '''
    此方法返回Local实例中获取ident的方法函数。
    '''
    

    4. set__ident_func_

    def _set__ident_func__(self, value):
        object.__setattr__(self._local, '__ident_func__', value)
    __ident_func__ = property(_get__ident_func__, _set__ident_func__)
    del _get__ident_func__,  _set__ident_func__
    '''
    此方法设置Local实例中获取ident的方法函数。
    '''
    

    5. call

    def __call__(self):
        def _lookup():
            rv = self.top
            if rv is None:
                raise RuntimeError('object unbound')
            return rv
        return LocalProxy(_lookup)
    '''
    在类中实现了__call__方法,那么实例对象也将成为一个可调用对象,那就可以像函数一样调用它。
    '''
    

    6. push

    def push(self, obj):
        """Pushes a new item to the stack"""
        rv = getattr(self._local, 'stack', None)
        if rv is None:
            self._local.stack = rv = []
        rv.append(obj)
        return rv
    '''
    结合Local源码的分析,我们知道push方法实现的是将对象obj放入字典Local.__storage__[ident]中key为 stack 对应的堆栈结构 (列表) 的value中。
    '''
    

    7. pop

    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:
            release_local(self._local)
            return stack[-1]
        else:
            return stack.pop()
        
    '''
    结合Local源码的分析,我们知道pop方法实现的是将从字典Local.__storage__[ident]中key为 stack 对应的堆栈结构 (列表) 取出最后一个元素。
    '''
    

    8. top

    @property
    def top(self):
        """The topmost item on the stack.  If the stack is empty,
        `None` is returned.
        """
        try:
            return self._local.stack[-1]
        except (AttributeError, IndexError):
            return None
    '''
    结合Local源码的分析,我们知道top方法实现的是返回字典Local.__storage__[ident]中key为 stack 对应的堆栈结构 (列表) 的最后一个元素。
    
    '''
    

    四、总结

    '''
    LocalStack 是在 Local 的基础上进行了二次封装,只是 LocalStack 维护的数据中 key 是固定的, 就是 stack, 而 value 值是栈的形式。
    '''
    希望你眼眸有星辰,心中有山海,从此以梦为马,不负韶华
  • 相关阅读:
    cloudstack secondary vm starting
    什么东西有机会
    ansible 远程以普通用户执行命令
    python 爬虫--同花顺-使用代理
    python3 Beautifulsoup <class 'bs4.element.ResultSet'> <class 'bs4.element.Tag'> 取值
    python3 raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 403: Forbid
    kubernetes 生命周期问题分析
    'utf-8' codec can't decode byte 0xbc in position 1182: invalid start byte
    找回Firefox4的状态栏!Status-4-Evar扩展
    生命周期和Zend引擎
  • 原文地址:https://www.cnblogs.com/daviddd/p/11917047.html
Copyright © 2020-2023  润新知