flask上下文管理

Posted qianzhengkai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)

以上是关于flask上下文管理的主要内容,如果未能解决你的问题,请参考以下文章

flask上下文管理

Flask上下文管理

flask 上下文管理 &源码剖析

flask之上下文管理

Flask 上下文管理

flask上下文管理