目录

TreadLocal对象

 Loacl对象

ThreadLocal变量 

 Flask_app上下文

应用上下文

Flask_request上下文


军训结束,我又回来了!!!!!!!!!!!!!!

TreadLocal对象

需求:实现并发效果

windows python3 flask 高并发_请求数据

 

windows python3 flask 高并发_flask_02

 Loacl对象

在Flask中,类似于request对象,其实是绑定到了一个werkzeug.local.Local对象上。

这样,即使是同一个对象,那么在多个线程中都是隔离的。类似的对象还有session对象。

from werkzeug.local import Local

ThreadLocal变量 

python提供的threadLocal变量,是一个全局变量。但是每一个线程都能保存自己的私有数据,私有数据,其他线程不可见。

在thread中的local: 

from threading import Thread,local

local = local()
local.request='这个是请求数据1'

class Mythread(Thread):
    def run(self):
        local.request='xiaolin'
        print(f'打印子线程的内容:{local.request}')

my_thread = Mythread()
my_thread.start()
my_thread.join()

print(f'主线程的内容:{local.request}')

在werkzeug中的local: 

from threading import Thread
from werkzeug.local import Local

local = Local()
local.request='这个是请求数据1'

class Mythread(Thread):
    def run(self):
        local.request='xiaolin'
        print(f'打印子线程的内容:{local.request}')

my_thread = Mythread()
my_thread.start()
my_thread.join()

print(f'主线程的内容:{local.request}')

没有什么区别其实,运行效果是一样的,但是在flask中用的还是werkzeug 模块。

只要满足绑定到"local"或"Local"对象上的属性,在每个线程中都是隔离的,那么他就叫做ThreadLocal对象,也叫'ThreadLocal'变量。

 Flask_app上下文

app上下文 = 应用上下文

理解:

程序里有很多外部变量(简单函数没有,例:add),有外部变量后,该程序就不能独立运行。要让他可以运行,则需要给所有的外部变量都设置一个值,这些值所在的集合就是上下文。(刚开始我也转不过来)

举例

运行的Flask项目,每一个路由映射的内容片段,都不可以单独拿出来使用。


当获取到了APP_Context以后,就可以直接通过程序映射的地址访问逻辑,并且可以重复使用。

应用上下文

应用上下文是存放到一个LocalStack的栈中。和应用app相关的操作就必须要用到应用上下文。

注意

在视图函数中,不用担心应用上下文的问题。因为视图函数要执行,那么肯定是通过访问url的方式执行的,

那么这种情况下,Flask底层就已经自动的帮我们把应用上下文都推入到了相应的栈中。

注意

如果想要在视图函数外面执行相关的操作,

比如: 获取当前的app名称,那么就必须要手动推入应用上下文

例:

获取通过current_app获取当前app的名字

from flask import Flask,current_app

app = Flask(__name__)

#方法1
# app_ctx = app.app_context()
# app_ctx.push()

# print(current_app.name)

#方法2
with app.app_context():
    print(current_app.name)

#print(current_app.name) 在没有将app推进stack里面前,不能使用。

@app.route('/')
def index():
    return f'hello,这是一个[{current_app.name}]引用'

if __name__ == '__main__':
    app.run(debug=True)

 用with语句可以直接帮我们把app推进stack里边。

Flask_request上下文

跟应用上下文一样,请求上下文也是存放在LocalStack 的栈中。和请求相关的操作就必须用到请求上下文。

在视图函数中,请求问题应该不需要我们去解决了,因为视图函数要执行,就肯定要通过访问url的方式来执行,这样的话Flask底层会自动帮我们把应用上下文和请求上下文都推入相应的栈中了。

但是如果要在视图函数外边进行相关的操作,就必须手动推入请求上下文。

底层代码执行说明:

1. 推入请求上下文到栈中,会首先判断有没有应用上下文

2. 如果没有那么就会先推入应用上下文到栈中

3. 然后再推入请求上下文到栈中

from flask import Flask,url_for

app = Flask(__name__)

@app.route('/')
def index():
    url = url_for('test_url')
    return f'hello =={url}'

@app.route('/test/')
def test_url():
    return '这是一个测试请求上下文'

# RuntimeError: Attempted to generate a URL without the application context being pushed. 
# This has to be executed when application context is available.

# with app.app_context():
#   url = url_for('test_url')
#   print(url)

# RuntimeError: Application was not able to create a URL adapter for request independent URL generation. 
# You might be able to fix this by setting the SERVER_NAME config variable.

with app.test_request_context():
    url = url_for('test_url') 
    print(url)

if __name__ == '__main__':
    app.run(debug=True)

关于上下文为什么要放入栈中?

1. 应用上下文:Flask底层是基于werkzeug,werkzeug是可以包含多个app的,所以这时候用一个栈来保存。

如果你在使用app1,那么app1应该是要在栈的顶部,如果用完了app1,那么app1应该从栈中删除。方便其他代码使用下面的app。

2. 如果在写测试代码,或者离线脚本的时候,我们有时候可能需要创建多个请求上下文,这时候就需要存放到一个栈中了。

使用哪个请求上下文的时候,就把对应的请求上下文放到栈的顶部,用完了就要把这个请求上下文从栈中移除掉。