在Flask中,类似于‘request‘的对象,其实是绑定到了一个‘werkzeug.local.Local‘对象上。这样即使是同一个对象,那么在多个线程中都是隔离的。类似的对象还有‘session‘以及‘g‘对象
Thread Local对象:
只有满足绑定到这个对象上的属性,在每个线程中都是隔离的,那么他就叫做Thread Local对象
应用上下文和请求上下文
应用上下文和请求上下文都是存放到一个‘LocalStack‘的栈中。和应用app相关的操作就必须要用到应用上下文。 比如通过‘current_app‘ 获取当前的这个‘app‘(也就是当前文件的名字).和请求相关的操作就必须用到请求上下文,比如使用‘usl_for’反转视图函数
1.在视图函数中,不用担心上下文的问题。因为视图函数要执行,那么肯定是通过访问url的方式执行的,那么这种情况下,Flask底层就已经自动的帮我们把请求上下文和应用上下文都推入到了相应的栈中
2.如果想要在视图函数外面执行相关的操作,比如获取当前的app(current_app),或者是反转url,那么就必须要手动推入相关的上下文:
手动推入app上下文:
第一种方式: app_context = app.app_context() app_context.push() 第二种方式: with app.app_context(): print(current_app)
手动推入请求上下文:推入请求上下文到栈中,会首先判断有没有应用上下文,如果没有,那么就会先推入应用上下文到栈中,然后再推入请求上下文到栈中
with app.test_request_context(): print(url_for(‘my_list‘))
为什么上下文需要放在栈中:
应用上下文: Flask底层是基于werkzeug, werkzeug是可以包含多个app的,所以这时候用一个栈来保存,如果你再使用app1,那么app1应该是要在栈的顶部,如果用完了app1,那么app1应该从栈中删除,方便其他代码使用下面的app
如果在写测试代码,或者离线脚本的时候,我们有时候可能需要创建多个请求上下文,这时候就需要存放到一个栈中了。使用哪个请求上下文的时候,就把对应的请求上下文放到栈的顶部,用完了就要把这个请求上下文从栈中移除掉
保存全局对象的g对象:
原文:https://www.cnblogs.com/fengzi759/p/12152533.html