zoukankan      html  css  js  c++  java
  • Flask核心机制:current_app

    请求上下文流程

    flask的request对象是一个全局对象,跟django的request不太一样,django的request对象是每次请求一个,但是flask全局就一个request对象,但是每次请求它能区分开是哪个请求,这个做的挺牛逼的,我去看了一下它的源码,原来是写了一个local类,来处理不同线程,每一个线程都用自己的reqeust对象,这样保证了使用的时候没有乱。
    请求上下文是ctx对象,内部有request和session对象
    应用上下文是app_ctx内部有g和app对象
    

    核心知识

    AppContext手动、自动入栈
    LocalStack是线程隔离的栈结构
    current_app是线程、协程隔离对象
    LocalProxy是获取当前线程隔离的代理对象

    AppContext、RequestContext、Flask与Request之间的关系

    AppContext
    应用上下文,是对flask一切对象的封装
    RequestContext
    请求上下文,是对request请求对象的封装
    current_app
    类型是LocalProxy
    像全局变量一样工作,但只能在处理请求期间且在处理它的线程中访问
    返回的栈顶元素不是应用上下文,而是flask的应用实例对象
    应用上下文的封装=flask核心对象+和外部协作对象(再flask封装对象上再添加push、pop等)(请求上下文同理)

    详解flask上下文与出入栈


    flask在RequestContext入栈前会检查另外一个AppContext的栈的情况,如果栈顶元素为空或者不是当前对象,就会把AppContext推入栈中,然后RequestContext才进栈。
    LocalStack作用是线程隔离
    LocalProxy 的作用就是可以根据线程/协程返回对应当前协程/线程的代理对象,也就是说

    线程 A 往 LocalStack中塞入 A
    线程 B 往 LocalStack 中塞入 B
    无论在是什么地方,调用LocalProxy,

    线程 A 永远取到得是 A,线程 B 取到得永远是 B

    有关Local、LocalStack的详解可以参考:http://python.jobbole.com/87738/

    这就是在 Flask 中可以在代码中直接使用 request、current_app 这样的变量的底层原因。

    应用上下文

      与请求上下文类似,当请求进来时,先实例化一个AppContext对象app_ctx,在实例化的过程中,提供了两个有用的属性,一个是app,一个是g。self.app就是传入的全局的app对象,self.g是一个全局的存储值的对象。接着将这个app_ctx存放到LocalStack()。

    class AppContext(object):
      def init(self, app):
        self.app = app
        self.url_adapter = app.create_url_adapter(None)
        self.g = app.app_ctx_globals_class()  

      视图函数中,我们就可以调用app对象和g对象,如果我们使用蓝图构建我们的项目时,在每一个直接引用app就会造成循环引用的异常,这时,应用上下文就会显得非常有用,我们可以直接调用current_app就可以在整个生命周期中使用我们的app对象了。比如使用我们的配置项:current_app.config

    current_app = LocalProxy(_find_app)
      最后,当视图函数执行结束后,从storage中pop掉app_ctx对象。

    from flask import Flask,request,session,g
    
    app = Flask(__name__)  # type:Flask
    
    @app.before_request
    def auth_demo():
        g.val = 123
    
    @app.route('/')
    def index():
        print(g.val)
        return "Hello World"
    
    if __name__ == '__main__':
        app.run()
    

    总结:flask中的上下文管理机制分为请求上下文和应用上下文两大方面,通过上下文的管理机制,实现了即去即用的一个特色。

  • 相关阅读:
    FFmpeg编程(二)FFmpeg中级开发
    Oracle锁表与解锁 对象锁与解锁
    index_combine and index_john
    oracle hint
    SAR
    组播IP地址
    Linux下使用tc(Traffic Control) 流量控制命令模拟网络延迟和丢包
    Linux服务器丢包故障的解决
    linux man page sections
    微服务架构统一安全认证设计与实践
  • 原文地址:https://www.cnblogs.com/whnbky/p/14330240.html
Copyright © 2011-2022 走看看