zoukankan      html  css  js  c++  java
  • 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()
    
    1. 上下文原理

    !/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)
    
    1. 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__')#!/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)
    
  • 相关阅读:
    挑战练习13.8 用于RecyclerView 的空视图
    挑战练习13.7 复数字符串资源
    挑战练习13.6 删除crime 记录
    挑战练习12.3 更多对话框
    20. Valid Parentheses
    挑战练习11.6 添加Jump to First按钮和Jump to Last按钮
    内存 分析
    HOOK64 32转换
    MD5
    HOOk快捷键
  • 原文地址:https://www.cnblogs.com/qianzhengkai/p/11386206.html
Copyright © 2011-2022 走看看