flask中的session源码解析(附图)请求上下文管理图以及文字解析
这里收藏一个小tips:
我们的项目在启动的时候会有很多的依赖插件需要安装,而且同一个插件还有很多版本,我们有一个工具包会帮我们解决这个问题,
pip3 install pipreqs
直接在cmd里面输入这个指令就可以获取这个插件,pipreqs
然后我们在项目的terminal里面输入指令:
pipreqs ./
就能得到一个文件,里面写了我们需要的所有依赖以及依赖的版本
flask中的上下文管理
文字输出:
当请求来的时候会把request和session封装到requestcontext里面,把app和g封装到Appcontent里面,然后再通过localstark把对象保存到stark里面,然后在处理视图的时候通过localproxy中的偏函数调用localstark,把所需数据取出来进行处理,当请求结束的时候通过localstark把session取出来,保存到cookie里面,而且会把stark中存储的对象进行删除.

1 s8day126 Flask上下文管理 2 3 内容回顾: 4 1. Linux命令(20个) 5 cd 6 vim 7 mkdir 8 ls 9 touch 10 cat 11 sed 12 13 2. 面向对象:特殊方法 14 obj['x'] = 123 15 obj.x = 123 16 obj + 123 17 3. functools 18 def func(a1,a2,a3): 19 return a1 + a2 + a3 20 21 v1 = func(1,2,3) 22 23 24 new_func = functools.partial(func,111,2) 25 new_func(3) 26 27 4. 你认识的装饰器?应用场景? 28 - 应用: 29 - flask:路由、before_request 30 - django: csrf、缓存、用户登录 31 32 5. Flask 33 - 蓝图 34 - session原理 35 36 37 38 今日内容: 39 1. threading.local 40 41 2. 上下文管理 42 43 3. 数据库连接池 44 45 内容详细: 46 1. threading.local 47 a. threading.local 48 作用:为每个线程开辟一块空间进行数据存储。 49 50 问题:自己通过字典创建一个类似于threading.local的东西。 51 storage={ 52 4740:{val:0}, 53 4732:{val:1}, 54 4731:{val:3}, 55 4712:{}, 56 4732:{}, 57 5000:{val:} 58 } 59 b. 自定义Local对象 60 作用:为每个线程(协程)开辟一块空间进行数据存储。 61 62 try: 63 from greenlet import getcurrent as get_ident 64 except Exception as e: 65 from threading import get_ident 66 67 from threading import Thread 68 import time 69 70 class Local(object): 71 72 def __init__(self): 73 object.__setattr__(self,'storage',{}) 74 75 def __setattr__(self, k, v): 76 ident = get_ident() 77 if ident in self.storage: 78 self.storage[ident][k] = v 79 else: 80 self.storage[ident] = {k: v} 81 82 def __getattr__(self, k): 83 ident = get_ident() 84 return self.storage[ident][k] 85 86 obj = Local() 87 88 def task(arg): 89 obj.val = arg 90 obj.xxx = arg 91 print(obj.val) 92 93 for i in range(10): 94 t = Thread(target=task,args=(i,)) 95 t.start() 96 97 98 99 2. 在源码中分析上下文管理 100 101 第一阶段:将ctx(request,session)放到“空调”上(Local对象) 102 103 第二阶段:视图函数导入:request/session 104 105 第三阶段:请求处理完毕 106 - 获取session并保存到cookie 107 - 将ctx删除 108 109 110 问题:flask中一共有几个LocalStack和Local对象 111 112 113 作业: 114 按组为单位,画Flask上下文管理 请求流程(类.方法) 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

1 # from threading import get_ident, Thread 2 # import time 3 # 4 # storage = {} 5 # 6 # 7 # def set(k, v): 8 # ident = get_ident() 9 # if ident in storage: 10 # storage[ident][k] = v 11 # else: 12 # storage[ident] = {k: v} 13 # 14 # 15 # def get(k): 16 # ident = get_ident() 17 # return storage[ident][k] 18 # 19 # 20 # def task(arg): 21 # set('val', arg) 22 # v = get('val') 23 # print(v) 24 # 25 # 26 # for i in range(10): 27 # t = Thread(target=task, args=(i,)) 28 # t.start() 29 30 # ===================================================================================== 31 # ===================================================================================== 32 try: 33 from greenlet import getcurrent as get_ident 34 except Exception as e : 35 from threading import get_ident 36 from threading import Thread 37 import time 38 39 40 class Arg(): 41 def __init__(self): 42 """ 43 44 """ 45 object.__setattr__(self, "storage", {}) 46 47 def __setattr__(self, k, v): 48 ident = get_ident() 49 50 if ident in self.storage: 51 self.storage[ident][k] = v 52 else: 53 self.storage[ident] = {k: v} 54 55 def __getattr__(self, k): 56 ident = get_ident() 57 return self.storage[ident][k] 58 59 60 obj = Arg() 61 62 63 def task(arg): 64 # obj.set('val', arg) 65 obj.xxx=arg 66 # v = obj.get('val') 67 obj.aaa=arg 68 print(obj.xxx) 69 70 71 for i in range(10): 72 t = Thread(target=task, args=(i,)) 73 t.start()
核心代码块:

1 # from threading import get_ident, Thread 2 # import time 3 # 4 # storage = {} 5 # 6 # 7 # def set(k, v): 8 # ident = get_ident() 9 # if ident in storage: 10 # storage[ident][k] = v 11 # else: 12 # storage[ident] = {k: v} 13 # 14 # 15 # def get(k): 16 # ident = get_ident() 17 # return storage[ident][k] 18 # 19 # 20 # def task(arg): 21 # set('val', arg) 22 # v = get('val') 23 # print(v) 24 # 25 # 26 # for i in range(10): 27 # t = Thread(target=task, args=(i,)) 28 # t.start() 29 30 # ===================================================================================== 31 # ===================================================================================== 32 try: 33 from greenlet import getcurrent as get_ident 34 except Exception as e : 35 from threading import get_ident 36 from threading import Thread 37 import time 38 39 40 class Arg(): 41 def __init__(self): 42 """ 43 这里是使用我们继承的父类里面的setattr方法,name设置为'storage',value设置为{}一个空字典 44 """ 45 object.__setattr__(self, "storage", {}) 46 47 def __setattr__(self, k, v): 48 ident = get_ident() 49 50 if ident in self.storage: 51 self.storage[ident][k] = v 52 else: 53 self.storage[ident] = {k: v} 54 55 def __getattr__(self, k): 56 ident = get_ident() 57 return self.storage[ident][k] 58 59 60 obj = Arg() 61 62 63 def task(arg): 64 # obj.set('val', arg)我们把这里的set方法改成了双下方法,就可以直接通过.去进行赋值操作 65 obj.xxx=arg 66 # v = obj.get('val') 67 obj.aaa=arg 68 print(obj.xxx) # 这里print就相当于调用get双下方法 69 70 71 for i in range(10): 72 t = Thread(target=task, args=(i,)) 73 t.start()
流程图:
=======================================================================================================================================
高逼格图解,关于flask的上下文管理机制