• flask上下文


    flask的request和session设置方式比较新颖,如果没有这种方式,那么就只能通过参数的传递。

    flask是如何做的呢?

    1. 本地线程,保证即使是多个线程,自己的值也是互相隔离。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import threading
    
    local_values = threading.local()
    
    
    def func(num):
        local_values.name = num
        import time
        time.sleep(1)
        print(local_values.name, threading.current_thread().name)
    
    
    for i in range(20):
        th = threading.Thread(target=func, args=(i,), name='线程%s' % i)
        th.start()
    

    2. 上下文原理

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from functools import partial
    from flask.globals import LocalStack, LocalProxy
    
    ls = LocalStack()
    
    
    class RequestContext(object):
        def __init__(self, environ):
            self.request = environ
    
    
    def _lookup_req_object(name):
        top = ls.top
        if top is None:
            raise RuntimeError(ls)
        return getattr(top, name)
    
    
    session = LocalProxy(partial(_lookup_req_object, 'request'))
    
    ls.push(RequestContext('c1')) # 当请求进来时,放入
    print(session) # 视图函数使用
    print(session) # 视图函数使用
    ls.pop() # 请求结束pop
    
    
    ls.push(RequestContext('c2'))
    print(session)
    
    ls.push(RequestContext('c3'))
    print(session)
    

    3. Flask内部实现

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from greenlet import getcurrent as get_ident
    
    
    def release_local(local):
        local.__release_local__()
    
    
    class Local(object):
        __slots__ = ('__storage__', '__ident_func__')
    
        def __init__(self):
            # self.__storage__ = {}
            # self.__ident_func__ = get_ident
            object.__setattr__(self, '__storage__', {})
            object.__setattr__(self, '__ident_func__', get_ident)
    
        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__()
            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)
    
    
    class LocalStack(object):
        def __init__(self):
            self._local = Local()
    
        def __release_local__(self):
            self._local.__release_local__()
    
        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
    
        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()
    
        @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
    
    
    stc = LocalStack()
    
    stc.push(123)
    v = stc.pop()
    
    print(v)
    

      

     
     
     
  • 相关阅读:
    HDU 2054 A == B ?(找小数点)
    javaWeb_使用标签库简化jsp
    EC2的维护更新-总结篇及有效经验分享
    SSLStrip 终极版 —— location 瞒天过海
    华为部分真机调试无法显示log问题解决
    LeetCode
    Tcl脚本调用高层API实现仪表使用和主机创建配置的自己主动化測试用例
    web工程调用hadoop集群1.2
    3DShader之移位贴图(Displacement Mapping)
    Java 学习第一天
  • 原文地址:https://www.cnblogs.com/aaronthon/p/9368545.html
Copyright © 2020-2023  润新知