flask-本地线程-请求上下文补充
context(上下文)是flask里面非常好的设计,使用flask需要非常理解应用上下文和请求上下文这两个概念
本地线程
本地线程(thread local)希望不同的线程对于内容的修改只在线程内部发挥作用,线程内部互相不影响
from django.test import TestCase
import threading mydata = threading.local()
mydata.number = 42 print(mydata.number) logs = [] def f():
mydata.number = 11
logs.append(mydata.number) thread = threading.Thread(target=f)
thread.start()
thread.join()
print(mydata.number)

可以看到,在线程的内部修改了mydata.number的值,但是没有影响到开始设置的值
本地线程的实现原理就是:在threading.current_thread().__dict__里添加一个包含对象mydata的id值的key,来保存不同的线程状态
werkzeug的Local
werkzeug自己实现了自己的本地线程。werkzeug.local.Local和threading.local的区别如下: werkzeug使用了自定义的__storage__来保存不同线程下的状态 werkzeug提供了释放本地线程的release_local方法 werkzeug使用了两种方法来通过get_ident函数获取线程的标识符*(greenlet,系统线程,默认使用系统的,如果安装了greenlet则使用她)
werkzeug还实现了两种数据结构。
localstack:基于werkzeug.local.Local实现的栈结构,可以将对象推入,弹出,也可以快速拿到栈顶对象 localproxy:作用和名字一样,是标准的代理模式。构造次结构时接收一个可以调用的参数(一般是函数),这个函数执行后就是通过localstack实例化的栈的栈顶对象。 基于localproxy对象的操作实力上都会转发到这个栈顶对象(也就是一个threadlocal上边)
Flask.request
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def xxx():
name = request.args.get("name")
在这里,我们先引用了flask.request,但是直到用户访问xxx函数的使用才通过request.args.get获取请求的参数值,试想,引用的时候还没发生这个请求,那么请求上下文是怎么获得的呢?
flask.request就是一个获取名为_request_ctx_stack的栈顶对象的LocalProxy实例:
from functools import partial
from werkzeug.local import LocalProxy def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError("xxxxx")
return getattr(top, name)
上面的逻辑可以正常使用,先来看看流程:
1:用户访问产生请求
2:在发生请求的过程中向_reqeust_ctx_stack推入这个请求的上下文对象,他会变成栈顶,request就会成为这个请求上下文,也就包含了这次请求的相关信息和数据
3:在视图函数中使用request就可以使用request.args.get('name')了
设想不使用LocalStack和LocalProxy的话,要想让视图函数访问的请求对象,就只能将其作为参数,一步步的传入视图函数中。这样做的缺点是会让每个视图函数都增加一个request参数,
而flask却巧妙的使用了上下文把某些对象设置成全局访问,每个线程看到的上下文对象却是不同的,这样就巧妙的解决了这个问题
使用上下文
应用上下文的典型场景是缓存一些在发生请求之前要使用到的资源,比如生成数据库链接和缓存一些对象;请求上下文发生在HTTP请求的开始,WSGI server调用Flask.__call__()之后。
应用上下文并不是应用启动之后生成的唯一上下文
······有空写吧,该吃饭了。。
flask-本地线程-请求上下文补充的更多相关文章
- 3、flask之基于DBUtils实现数据库连接池、本地线程、上下文
本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...
- flask之基于DBUtils实现数据库连接池、本地线程、上下文
本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...
- Flask中的ThreadLocal本地线程,上下文管理
先说一下和flask没有关系的: 我们都知道线程是由进程创建出来的,CPU实际执行的也是线程,那么线程其实是没有自己独有的内存空间的,所有的线程共享进程的资源和空间,共享就会有冲突,对于多线程对同一块 ...
- Flask系列10-- Flask请求上下文源码分析
总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...
- flask上下文全局变量,程序上下文、请求上下文、上下文钩子
Flask上下文 Flask中有两种上下文,程序上下文(application context)和请求上下文(request context) 当客户端发来请求时,请求上下文就登场了.请求上下文里包含 ...
- Flask 上下文管理-- (session,request,current_app的传递)--类似本地线程实现,以及多app应用
Flask session,request,current_app的传递 请求上下文的作用 -- 封装请求相关得数据(request,session) 请求上下文 request session re ...
- flask请求上下文
先看一个例子: #!/usr/bin/env python # -*- coding:utf-8 -*- import threading # local_values = threading.loc ...
- Flask--偏函数, 线程安全, 请求上下文
一 . 偏函数 from functools import partial def func(a, b): return a + b new_func = partial(func, 3, 4) # ...
- python 全栈开发,Day139(websocket原理,flask之请求上下文)
昨日内容回顾 flask和django对比 flask和django本质是一样的,都是web框架. 但是django自带了一些组件,flask虽然自带的组件比较少,但是它有很多的第三方插件. 那么在什 ...
随机推荐
- 电子邮件中的to、cc、bcc
电子邮件中的to.cc(carbon copy)和bcc(blind carbon copy),分别是收件人.抄送.密送 to 收件人 你想要给其发邮件的人 cc 抄送人 cc和to是一样的,但是cc ...
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Problem K Tournament Wins
Problem K — limit 1 second Tournament Wins 这个题就是有2^n队伍,他现在的实力水平是第k位,采用的是淘汰制 问一下你他的胜场数的期望 这人能 win> ...
- javascript异常cannot read property xx of null 的错误
一般报这种异常或者错误,是因为试图从null中再读一个属性导致的. 比如:var myAttr=myObj.data.Name; 假如这个时候myObj.data是null,那么再试图读取data的N ...
- HDU-5423 Rikka with Tree。树深搜
Rikka with Tree 题意:给出树的定义,给出树相似的定义和不同的定义,然后给出一棵树,求是否存在一颗树即和其相似又与其不同.存在输出NO,不存在输出YES. 思路:以1号节点为根节点,我们 ...
- 九度oj 题目1472:求两个多项式的和
题目描述: 输入两个多项式,计算它们的和. 每个多项式有若干对整数表示,每组整数中,第一个整数表示系数(非0),第二个整数表示该项的次数. 如由3 3 5 -2 1 4 0表示3x^5 - 2 * x ...
- hdu6060[贪心+dfs] 2017多校3
/* hdu6060[贪心+dfs] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long L ...
- BZOJ-1269 文本编辑器
.... 这道题就是Noi原题嘛...虽然更容易写... 题意: 建立一个数据结构,并支持以下操作: Insert 区间插入有序序列:Delete 区间删除:Rotate 区间翻转:Get 单点查询 ...
- 史上最详细的linux关于connect: network is unreachable 问题的解决方案
1.虚拟机常用连接网络方式有两种:桥接和NAT. 使用桥接模式:则保证虚拟机的网段与物理机的网段保持一致.如下: 虚拟机网卡配置: 物理机使用WiFi接入网络(我用的是WiFi,你们可能用的是有线道理 ...
- Jackson工具类(各种转换)
首先要在项目中引入jackson的jar包(在此不做说明) 下面直接上代码 public class JacksonUtils { private final static ObjectMapper ...
- 玩具装箱 BZOJ 1010
玩具装箱 [问题描述] P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...