flask核心机制

flask的经典错误:working outside application context,不在上下文环境中

flask提供两种上下文:应用上下文(AppContext)和请求上下文(RequestContext)

应用上下文提供对核心对象Flask的封装,请求上下文是对请求对象Request的封装

 

AppContext把实例化的app作为属性存放

 

 这个AppContext对象下面定义了四个方法:push、pop、enter、exit

RequestContext同样定义相同的四个方法,这四个方法和栈结构是紧密相关的

Flask核心对象存储在Appcontext对象中,而Request请求对象存储在RequestContext中

外部的一些参数或者数据和flask核心对象Flask一起组成新的对象就是上下文,同时在上下文上面提供一系列方法

 

Flask核心对象里面承载各种功能,如配置文件信息,提供注册路由或者视图函数功能

Request请求对象保存了请求信息,相关URL的参数等

操作这两个对象不是from引入使用,而是从context间接拿到对象,context也不是引入使用

current_app和request的localProxy提供了间接操纵上下文的能力

代理模式的实现涉及到flask的一系列机制,如下图

 

 

 当一个请求进入flask中之后,flask首先会实例化一个RequestContext请求上下文,它封装了此次请求的相关信息,在Request中,当实例化请求上下文后会把它推入栈中

栈:后进先出    队列:先进先出

flask用LocalStack来表示一个栈,将LocalStack实例化存储在_request_ctx_stack中,或者_app_ctx_stack中

入栈就是用四个方法中的push方法实现的,RequestContext入栈之前会先检查_app_ctx_stack栈顶元素是否为空,如果空,会先推入一个AppContext对象进栈,然后推入RequestContext

 当操作current_app(LocalProxy)和request(LocalProxy)这两个代理时相当于间接操作两个栈顶的元素,也就是两个上下文,当两个栈顶元素不为空,就不会出现working outside application context这种错误

想要避免这种错误就需要把上下文推入栈中,首先要先得到应用上下文对象,flask核心对象提供一个方法app.app_context得到flask的AppContext

from flask import Flask, current_app

app = Flask(__name__)

ctx = app.app_context()

ctx.push()

a = current_app

b = current_app.config['DEBUG']

ctx.pop()

 

最终current_app返回了flask的核心对象,而不是应用上下问

current_app: "Flask" = LocalProxy(_find_app)

def _find_app():
  top = _app_ctx_stack.top
  if top is None:
    raise RuntimeError(_app_ctx_err_msg)
  return top.app

 

还有一种简便的方法就是使用with

with app.app_context():

  a = current_app()

  b = current_app.config['DEBUG']

 

posted @ 2021-11-29 23:26  安静ovo  阅读(76)  评论(0编辑  收藏  举报