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. _getident_func

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

4. _setident_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 值是栈的形式。
'''

原文地址:https://www.cnblogs.com/daviddd/p/11917047.html

时间: 2024-07-30 06:29:51

Werkzeug之LocalStack源码解析的相关文章

Werkzeug之Local源码解析

Werkzeug之Local源码解析 原博客地址 http://liuyajing.coding.me/blogs/python/2018/werkzeug-local/ 一.引入 最近在阅读 Flask 的源码,遇到三个概念:Local . LocalStack 和 LocalProxy ,本文主要就针对 Local 概念及其源码进行原理剖析. 二.Local Local 是一个类,源码位置:site-packages/werkzeug/local.py 在模块的开头,有以下代码: # 由于每

ChrisRenke/DrawerArrowDrawable源码解析

转载请注明出处http://blog.csdn.net/crazy__chen/article/details/46334843 源码下载地址http://download.csdn.net/detail/kangaroo835127729/8765757 这次解析的控件DrawerArrowDrawable是一款侧拉抽屉效果的控件,在很多应用上我们都可以看到(例如知乎),控件的github地址为https://github.com/ChrisRenke/DrawerArrowDrawable

五.jQuery源码解析之jQuery.extend(),jQuery.fn.extend()

给jQuery做过扩展或者制作过jQuery插件的人这两个方法东西可能不陌生.jQuery.extend([deep],target,object1,,object2...[objectN]) jQuery.fn.extend([deep],target,object1,,object2...[objectN])这两个属性都是用于合并两个或多个对象的属性到target对象.deep是布尔值,表示是否进行深度合并,默认是false,不执行深度合并.通过这种方式可以在jQuery或jQuery.fn

eclipse中导入jdk源码、SpringMVC注解@RequestParam、SpringMVC文件上传源码解析、ajax上传excel文件

eclipse中导入jdk源码:http://blog.csdn.net/evolly/article/details/18403321, http://www.codingwhy.com/view/799.html. ------------------------------- SpringMVC注解@RequestParam:http://825635381.iteye.com/blog/2196911. --------------------------- SpringMVC文件上传源

String源码解析(一)

本篇文章内的方法介绍,在方法的上面的注释讲解的很清楚,这里只阐述一些要点. Java中的String类的定义如下: 1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { ...} 可以看到,String是final的,而且继承了Serializable.Comparable和CharSequence接口. 正是因为这个特性,字符串对象可以被共享,例如下面

Flume-ng源码解析之Channel组件

如果还没看过Flume-ng源码解析之启动流程,可以点击Flume-ng源码解析之启动流程 查看 1 接口介绍 组件的分析顺序是按照上一篇中启动顺序来分析的,首先是Channel,然后是Sink,最后是Source,在开始看组件源码之前我们先来看一下两个重要的接口,一个是LifecycleAware ,另一个是NamedComponent 1.1 LifecycleAware @[email protected] interface LifecycleAware {  public void s

Spring源码解析-applicationContext

Demo uml类图 ApplicationContext ApplicationListener 源码解析 主流程 obtainFreshBeanFactory prepareBeanFactory invokeBeanFactoryPostProcessors registerBeanPostProcessors registerListeners finishRefresh 总结 在已经有BeanFactory可以完成Ioc功能情况下,spring又提供了ApplicationContex

socketserver源码解析和协程版socketserver

来,贴上一段代码让你仰慕一下欧socketserver的魅力,看欧怎么完美实现多并发的魅力 client import socket ip_port = ('127.0.0.1',8009) sk = socket.socket() sk.connect(ip_port) sk.settimeout(5) while True: data = sk.recv(1024) print('receive:',data.decode()) inp = input('please input:') sk

Handler机制(四)---Handler源码解析

Handler的主要用途有两个:(1).在将来的某个时刻执行消息或一个runnable,(2)把消息发送到消息队列. 主要依靠post(Runnable).postAtTime(Runnable, long).postDelayed(Runnable, long).sendEmptyMessage(int).sendMessage(Message).sendMessageAtTime(Message).sendMessageDelayed(Message, long)这些方法来来完成消息调度.p