1.1.local线程隔离对象

不用local对象的情况

  1. from threading import Thread
  2.  
  3. request = ''
  4.  
  5. class MyThread(Thread):
  6. def run(self):
  7. global request
  8. request = 'abc'
  9. print('子线程',request) #子线程 abc
  10.  
  11. mythread = MyThread()
  12. mythread.start()
  13. mythread.join()
  14.  
  15. print('主线程',request) #主线程 abc

如果用local对象,在每个线程中都是隔离的

  1. from threading import Thread
  2. from werkzeug.local import Local
  3.  
  4. locals = Local()
  5. locals.request = ''
  6.  
  7. class MyThread(Thread):
  8. def run(self):
  9. locals.request = 'abc'
  10. print('子线程',locals.request) #子线程 abc
  11.  
  12. mythread = MyThread()
  13. mythread.start()
  14. mythread.join()
  15.  
  16. print('主线程',locals.request) #主线程 123

1.2.app上下文和request上下文

应用上下文和请求上下文都是存放在一个‘LocalStack’的栈中,和应用app相关的操作就必须要用到应用上下文,比如通过current_app获取当前的这个app的名字。和请求相关的操作就必须用到请求上下文,比如使用url_for反转视图函数。

  • 在视图函数中,不用担心上下文的问题,因为视图函数要执行,name肯定是通过访问url的方式执行的,name这种情况下,Flask底层就已经自动的帮我们把请求上年文和应用上下文都推入到了相应的栈中。
  • 如果想要在视图函数外面执行相关的操作,name就必须要手动推入相关的上下文
  • 手动推入请求上下文:推入请求上下文到栈中,会首先判断有没有应用上下文,如果没有那么就会先推入应用上下文到栈中,然后再推入请求上下文到栈中。

app上下文

  1. from flask import Flask,current_app
  2.  
  3. app = Flask(__name__)
  4.  
  5. #如果在视图函数外部访问,则必须手动推入一个app上下文到app上下文栈中
  6. #第一种方法
  7. # app_context = app.app_context()
  8. # app_context.push()
  9. # print(current_app.name)
  10.  
  11. #第二种方法
  12. with app.app_context():
  13. print(current_app.name) #context_demo
  14.  
  15. @app.route('/')
  16. def index():
  17. # 在视图函数内部可以直接访问current_app.name
  18. print(current_app.name) #context_demo
  19. return 'Hello World!'
  20.  
  21. if __name__ == '__main__':
  22. app.run(debug=True)

请求上下文

  1. from flask import Flask,current_app,url_for
  2.  
  3. app = Flask(__name__)
  4.  
  5. #应用上下文
  6. #如果在视图函数外部访问,则必须手动推入一个app上下文到app上下文栈中
  7. with app.app_context():
  8. print(current_app.name) #context_demo
  9.  
  10. @app.route('/')
  11. def index():
  12. # 在视图函数内部可以直接访问current_app.name
  13. print(current_app.name) #context_demo
  14. return 'Hello World!'
  15.  
  16. @app.route('/list/')
  17. def my_list():
  18. return 'my_list'
  19.  
  20. # 请求上下文
  21. with app.test_request_context():
  22. # 手动推入一个请求上下文到请求上下文栈中
  23. # 如果当前应用上下文栈中没有应用上下文
  24. # 那么会首先推入一个应用上下文到栈中
  25. print(url_for('my_list'))
  26.  
  27. if __name__ == '__main__':
  28. app.run(debug=True)

为什么上下文需要放在栈中?

1.应用上下文:

Flask底层是基于werkzeug,werkzeug是可以包含多个app的,所以这时候用一个栈来保存,如果你在使用app1,那么app1应该是要在栈的顶部,如果用完了app1那么app应该从栈中删除,方便其他代码使用下面的app。

2.请求上下文:

如果在写测试代码,或者离线脚本的时候,我们有时候可能需要创建多个请求上下文,这时候就需要存放到一个栈中了。使用哪个请求上下文的时候,就把对应的请求上下文放到栈的顶部,用完了就要把这个请求上下文从栈中移除掉。

1.3.线程隔离的g对象

g对象是在整个Flask应用运行期间都是可以使用的,并且它也是跟request一样是线程隔离的。这个对象是专门用来存储开发者自定义的一些数据,方便在整个Flask程序中都可以使用。一般使用就是,将一些经常会用到的数据绑定到上面,以后就直接从g上面取就可以了,而不是通过传参的形式,这样更加方便。

10.Flask上下文的更多相关文章

  1. flask上下文详解

    一.前言 了解过flask的python开发者想必都知道flask中核心机制莫过于上下文管理,当然学习flask如果不了解其中的处理流程,可能在很多问题上不能得到解决,当然我在写本篇文章之前也看到了很 ...

  2. Flask 上下文(Context)原理解析

    :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...

  3. Flask上下文管理机制

    前引 在了解flask上下文管理机制之前,先来一波必知必会的知识点. 面向对象双下方法 首先,先来聊一聊面向对象中的一些特殊的双下划线方法,比如__call__.__getattr__系列.__get ...

  4. 4.1 python类的特殊成员,偏函数,线程安全,栈,flask上下文

    目录 一. Python 类的特殊成员(部分) 二. Python偏函数 1. 描述 2. 实例一: 取余函数 3. 实例二: 求三个数的和 三. 线程安全 1. 实例一: 无线程,消耗时间过长 2. ...

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

    一.一些python的知识 1.偏函数 def add(x, y, z): print(x + y + z) # 原本的写法:x,y,z可以传任意数字 add(1,2,3) # 如果我要实现一个功能, ...

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

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

  7. Flask上下文管理

    一.一些python的知识 1.偏函数 def add(x, y, z): print(x + y + z) # 原本的写法:x,y,z可以传任意数字 add(1,2,3) # 如果我要实现一个功能, ...

  8. Flask 上下文机制和线程隔离

    1. 计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决, 上下文机制就是这句话的体现. 2. 如果一次封装解决不了问题,那就再来一次 上下文:相当于一个容器,保存了Flask程序运行过程中 ...

  9. 详解Flask上下文

    上下文是在Flask开发中的一个核心概念,本文将通过阅读源码分享下其原理和实现. Flask系列文章: Flask开发初探 WSGI到底是什么 Flask源码分析一:服务启动 Flask路由内部实现原 ...

随机推荐

  1. 普通用户添加sudo权限

    1.切换超级用户 su - root 2.编辑配置文件 vim /etc/sudoers ## Allow root to run any commands anywhere root ALL=(AL ...

  2. mac os x 查看网络端口情况

    查看端口是否打开 使用 netstat 命令 a. `netstat -nat | grep <端口号>` , 如命令 `netstat -nat | grep 3306` b. `net ...

  3. 使用handler倒计时

    package com.example.jikangwang.myapplication; import android.content.Intent; import android.os.Handl ...

  4. LOJ 6019

    挺没意思的题 全都读进去算一个每个阶乘的系数 然后算一遍每个数的系数 最后在质数处算一下答案 #include<bits/stdc++.h> using namespace std; #d ...

  5. 用clumsy模拟丢包测试socket库的失败重传

    用python的socket库写了通信小程序,现在我需要通过软件模拟出在网络极差的情况下,socket底层解决丢包问题的能力怎么样,我一开始想的是分别在linux和windowns下分别测试,后来一想 ...

  6. 检查对象是否为NULL或者为Empty

    不管是在Winform开发,还是在asp.net 开发中当从一个数据源中获取数据时你总是不知道这个数据的状态,这个时候总要对她进行一次判断,不过每次进行一次判断总是要写怎么一堆代码,时间长了,总感觉不 ...

  7. 查看Oracle中存储过程长时间被卡住的原因

    1:查V$DB_OBJECT_CACHE SELECT * FROM V$DB_OBJECT_CACHE WHERE name='CUX_OE_ORDER_RPT_PKG' AND LOCKS!='0 ...

  8. IOS开发中将定时器添加到runLoop中

    runLoop主要就是为线程而生的.他能够让线程在有任务的时候保持工作状态,没有任务的时候让线程处于休眠待备状态. 主线程的runloop默认是开启的.主线程上创建的定时器已经默认添加到runLoop ...

  9. 查看 FormData 中已存在的值

    var formData = new FormData(); formData.append('name','bob'); formData.append('sex','male'); formDat ...

  10. linux学习:用户管理

    一.管理用户(user) 主要工具命令 useradd    注:添加用户 adduser    注:添加用户 passwd     注:为用户设置密码 usermod    注:修改用户命令,可以通 ...