flask上下文管理相关 - threading.local 以及原理剖析

threading.local

面向对象相关: setattr/getattr

class Foo(object):
    pass

obj = Foo()
obj.x1 = 123
# object.__setattr__(obj,'x1',123)

print(obj.x1)
# object.__getattr__(obj,'x1')

Local类的模拟

简易版

class Local(object):
    def __init__(self):
        # self.storage = {}
        object.__setattr__(self,'storage',{})

    def __setattr__(self, key, value):
        self.storage[key] = value

    def __getattr__(self, item):
        return self.storage[item]

obj = Local()

obj.x1 = 123

print(obj.x1)

升级版

import threading
"""
{
    1231:{x1:0},
    1432:{x1:1},
    ...
    5321:{x1:9}
}
"""
class Local(object):
    def __init__(self):
        # self.storage = {}
        object.__setattr__(self,'storage',{})

    def __setattr__(self, key, value):
        # self.storage[key] = value
        ident = threading.get_ident() # 1233
        if ident in self.storage:
            self.storage[ident][key] = value
        else:
            self.storage[ident] = {key:value}

    def __getattr__(self, item):
        ident = threading.get_ident()
        return self.storage[ident][item]

obj = Local()

def task(arg):
    obj.x1 = arg
    print(obj.x1)

for i in range(10):
    t = threading.Thread(target=task,args=(i,))
    t.start()

源码

class Local(object):
    __slots__ = ("__storage__", "__ident_func__")

    def __init__(self):
        object.__setattr__(self, "__storage__", {})
        object.__setattr__(self, "__ident_func__", get_ident)

    def __iter__(self):
        return iter(self.__storage__.items())

    def __call__(self, proxy):
        """Create a proxy for a name."""
        return LocalProxy(self, proxy)

    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)

原文地址:https://www.cnblogs.com/jjzz1234/p/12037050.html

时间: 2024-08-03 20:13:44

flask上下文管理相关 - threading.local 以及原理剖析的相关文章

flask上下文管理之threading.local

Flask之上下文管理 知识储备之问题情境: request中的参数: 单进程单线程 单进程多线程-->reqeust 会因为多个请求,数据发生错乱.--->可以基于threading.local对象 单进程单线程(多协程)threading.local对象做不到(因为一个线程下多个协程同享一个线程的资源) 解决办法: ? 自定义类似threading.local对象(支持协程)---保证多协程下数据的安全 先来看一下下面这段代码(支持多线程): # -*- coding: utf-8 -*-

Flask上下文管理、session原理和全局g对象

一.一些python的知识 1.偏函数 def add(x, y, z): print(x + y + z) # 原本的写法:x,y,z可以传任意数字 add(1,2,3) # 如果我要实现一个功能,这三个数中,其中一个数必须是3 # 我们就可以使用偏函数来帮着我们传参 from functools import partial # partial:给add这个函数固定传一个数字 3 new_add = partial(add, 3) # 因此新的函数只需要传2个参数 new_add(1,1)

Flask 上下文管理-- (session,request,current_app的传递)

Flask session,request,current_app的传递 1 flask的 request, session 和 current_app 都是 设置方式比较新颖 -- 通过上下文管理的方式实现的 每次请求进来app.run调用 call 方法, 创建 一个本地线程(唯一标识作为键) -- 然后把实例化的对象push到一个地方,在请求结束后返回的时候 pop 掉 local = { '标识':{'stack':[RequestContext(),]} } 2 补充 partial

flask上下文管理

flask的上下文管理分应用上下文和请求上下文: 官方文档里是说先理解应用上下文比较好,不过我还是觉得反过来,从请求上下文开始记录比较合适,所以这篇先记录请求上下文. 那么问题来了,什么才是请求上下文: 通俗点说,其实上下文就像一个容器,包含了很多你需要的信息 request和session都属于请求上下文 request 针对的是http请求作为对象 session针对的是更多是用户信息作为对象 上下文的结构 说到上下文这个概念的数据结构,这里需要先知道,他是运用了一个Stack的栈结构,也就

Flask 上下文管理

flask的request和session设置方式比较新颖,如果没有这种方式,那么就只能通过参数的传递. flask是如何做的呢? 1.Python 实现的本地线程 保证即使是多个线程,自己的值也是互相隔离. import threading local_values = threading.local() def func(num): local_values.name = num import time time.sleep(1) print(local_values.name, threa

python - Flask 上下文管理 流程

上下文管理:    - 请求上下文 (ctx=RequestContext())  : request/session    - App上下文  (app_ctx=AppContext())  : app/g 1. 请求进来执行 __call__ 方法.2. __call__ 方法调用 wsgi_app.3. wsgi_app:    - (1)实例化两个方法:    ctx = RequestContext(request,session)    app_ctx = AppContext(ap

利用flask上下文管理原理,实现线程之间的数据安全

由于一般的程序基本上都是IO密集型,如果只是为了保证数据的安全而去开启进程,这必定是浪费资源的行为:为了保证数据的安全,借用flask的上下文的原理,如下代码实现 from threading import Threadimport time try: from greenlet import getcurrent as get_ident # 协程的唯一标识except ImportError: try: from thread import get_ident except ImportEr

深度剖析Flask上下文管理机制

前言 上下文这个概念多见于文章中,是一句话中的语境,也就是语言环境.一句莫名其妙的话出现会让人不理解什么意思,如果有语言环境的说明,则会更好,这就是语境对语意的影响. 上下文是一种属性的有序序列,为驻留在环境内的对象定义环境.在对象的激活过程中创建上下文,对象被配置为要求某些自动服务,如同步.事务.实时激活.安全性等等. 如在计算机中,相对于进程而言,上下文就是进程执行时的环境.具体来说就是各个变量和数据,包括所有的寄存器变量.进程打开的文件.内存信息等.可以理解上下文是环境的一个快照,是一个用

12. Flask的上下文管理

一.Threading.local 通过Threading.local实现本地存储隔离:当我们开启多线程来执行func函数,通过自定义的Foo类来存储数据时,我们发现最终的输出结果是全部的线程打印的都是一个最终的数字10,这是因为这样存储的数据线程之间是共享的,当最后一个线程执行func函数时,由于func函数time.sleep了1秒钟,第一个线程还没有来得及打印数据呢,就被最后一个线程传的参数给覆盖了,从而线程们打印的结果都是相同的. from threading import local