Flask上下文和"working outside application context"

一、原因

  1. 对象的应用超出了应用上下文的范围
  2. _app_ctx_stack为空

二、解决办法

act = app.app_context()
act.push()
# current_app.xxxxx 应用操作
act.pop()

注:pycharm断点调试时,current_app可能会显示LocalProxy:unbound。鼠标放到current_app上会显示正确的内容。

三、深入理解

  1. Flask上下文
    1. AppContext:封装了Flask实例对象和一些其他方法和参数。
    2. RequestContext:封装了Request对象和一些其他方法和参数。
    3. 都包含push()pop()__enter__()__exit__()方法。
    4. 编程的过程中使用Flask Request对象,要从上下文中获取。
  2. 出入栈
    1. 收到一个请求,封装到RequestContext中,检查LocalStack(应用上下文的栈)的栈顶是否为空,如果为空,将AppContext推入(push())到栈(_app_ctx_stack)中,再把RequestContext推入栈(_request_ctx_stack)中。当请求结束时,两个栈中的元素会被弹出(pop())。
    2. current_apprequest 都(LocalProxy)指向应用上下文和请求上下文栈的栈顶元素。返回的是Flask实例对象app和请求对象request
    3. 手动入栈、出栈
      1. act = app.app_context() 获取AppContext
      2. act.push() 推入_app_ctx_stack
      3. act.pop() 出栈,删除元素
      4. 手动的出入栈一般应用到离线应用和单元测试。

四、上下文管理器

  1. 基本概念
    1. 上下文协议:实现了__enter__()__exit__()两个方法,即实现了上下文协议;
    2. 上下文管理器:实现了上下文协议的对象。
    3. 上下文表达式:with语句,且with必须返回上下文管理器。
  2. __enter__()
    1. with demo() as d:   d的值是__enter__()方法返回的值
  3. __exit__()
    1. __exit__方法返回的是布尔型值。如果with代码块中的内容出现异常,__exit__返回的是False,且会抛出异常。反之返回True
    2. __exit__方法需传4个参数,除self的另外三个是exc_typeext_valuetb。出现异常时,exc_type值为异常的类型;ext_value值为异常的描述;tb值为异常的堆栈信息。
  4. 应用
    1. 资源的链接和释放。
    2. 因此手动出入栈可写为:
with app.app_context() as atc:
    #atc.xxxx
    #xxxx

猜你喜欢

转载自www.cnblogs.com/blueandsky/p/11628480.html
今日推荐