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-本地线程-请求上下文补充的更多相关文章

  1. 3、flask之基于DBUtils实现数据库连接池、本地线程、上下文

    本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...

  2. flask之基于DBUtils实现数据库连接池、本地线程、上下文

    本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...

  3. Flask中的ThreadLocal本地线程,上下文管理

    先说一下和flask没有关系的: 我们都知道线程是由进程创建出来的,CPU实际执行的也是线程,那么线程其实是没有自己独有的内存空间的,所有的线程共享进程的资源和空间,共享就会有冲突,对于多线程对同一块 ...

  4. Flask系列10-- Flask请求上下文源码分析

    总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...

  5. flask上下文全局变量,程序上下文、请求上下文、上下文钩子

    Flask上下文 Flask中有两种上下文,程序上下文(application context)和请求上下文(request context) 当客户端发来请求时,请求上下文就登场了.请求上下文里包含 ...

  6. Flask 上下文管理-- (session,request,current_app的传递)--类似本地线程实现,以及多app应用

    Flask session,request,current_app的传递 请求上下文的作用 -- 封装请求相关得数据(request,session) 请求上下文 request session re ...

  7. flask请求上下文

    先看一个例子: #!/usr/bin/env python # -*- coding:utf-8 -*- import threading # local_values = threading.loc ...

  8. Flask--偏函数, 线程安全, 请求上下文

    一 . 偏函数 from functools import partial def func(a, b): return a + b new_func = partial(func, 3, 4) # ...

  9. python 全栈开发,Day139(websocket原理,flask之请求上下文)

    昨日内容回顾 flask和django对比 flask和django本质是一样的,都是web框架. 但是django自带了一些组件,flask虽然自带的组件比较少,但是它有很多的第三方插件. 那么在什 ...

随机推荐

  1. 详解Java类的生命周期

    引言 最近有位细心的朋友在阅读笔者的文章时,对Java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内Java方面的教材大多只是告 ...

  2. 向php数组添加元素的方法哪种更高效

    $arr = array(); // 第一种 array_push($arr, 'test'); // 第二种 $arr[] = 'test'; 参考PHP官方文档:http://php.net/ma ...

  3. xtu数据结构 I. A Simple Tree Problem

    I. A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB 64-bit integer IO format: %lld     ...

  4. 安卓Toast实现

    代码改变世界 Toast实现显示 // 第一个参数:当前的上下文环境.可用getApplicationContext()或this // 第二个参数:要显示的字符串.也可是R.string中字符串ID ...

  5. 安卓手机 HTML5 手机页面 输入表单被键盘遮挡住了

    TML5 手机页面 输入表单被键盘遮挡住了 请问 大神 怎么 js 或者 JQ 判断安卓手机软键盘的键盘隐藏键按下去了? 有使用 uexWindow 方法 能判断到确定键 是 13 但是不知道这个键的 ...

  6. 【bzoj3123】[Sdoi2013]森林 倍增LCA+主席树+启发式合并

    题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...

  7. VM上完美运行macos

    VM上完美运行macos 作者:方辰昱 时间:十月三号 效果图 简要步骤 下载安装VM 下载镜像文件链接,darwin.iso,unlocker,beamoff.合集下载链接:https://pan. ...

  8. [BZOJ4756] [Usaco2017 Jan]Promotion Counting(线段树合并)

    传送门 此题很有意思,有多种解法 1.用天天爱跑步的方法,进入子树的时候ans-query,出去子树的时候ans+query,query可以用树状数组或线段树来搞 2.按dfs序建立主席树 3.线段树 ...

  9. POJ 2914 Minimum Cut 全局最小割

    裸的全局最小割了吧 有重边,用邻接矩阵的时候要小心 #include<iostream> #include<cstdio> #include<bitset> #in ...

  10. Django REST

    一.什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度 ...