python - Flask 上下文管理 流程

上下文管理:
    - 请求上下文 (ctx=RequestContext())  : request/session
    - App上下文  (app_ctx=AppContext())  : app/g

1. 请求进来执行 __call__ 方法。
2. __call__ 方法调用 wsgi_app。
3. wsgi_app:
    - (1)实例化两个方法:
    ctx = RequestContext(request,session)
    app_ctx = AppContext(app,g)
    - (2) 调用push方法(push方法实例化):
    _app_ctx_stack = LocalStack()     --> local = Local() --> __storage__ = {线程号:{stack:[app_ctx]}}
    _request_ctx_stack = LocalStack() --> local = Local() --> __storage__ = {线程号:{stack:[ctx]}}

- PS:
        _app_ctx_stack = LocalStack() 和 _request_ctx_stack = LocalStack() 执行过程中会有:
            push(), top(), pop() 方法来维护

3.5 在这个地方可能会执行 @app.before_request 等特殊装饰器

4. 视图函数:
    - 调用 request.method  --> request = LocalProxy(partial(_lookup_req_object, ‘request‘))
    - 调用 session[‘q‘]    --> session = LocalProxy(partial(_lookup_req_object, ‘session‘))    
        - request 和 session 会调用各自的偏函数,偏函数找到 top 方法, top方法返回 ctx.request/ctx.session,
          然后偏函数会将ctx结果返回到上面两个方法中(LocalProxy), 在LocalProxy方法中再次取值(ctx.request.method/ctx.session[‘q‘]), 再将取出来的值返回到视图

- 调用 current_app     --> current_app = LocalProxy(_find_app)
    - 调用 g                      --> g = LocalProxy(partial(_lookup_app_object, ‘g‘))
        - current_app 和 g 也是会调用各自的偏函数, 偏函数找到 top 方法, top方法返回 app_ctx.app/app_ctx.g,
          然后偏函数会将app_ctx结果返回到上面两个方法中(LocalProxy), 在LocalProxy方法中再次取值(app_ctx.app/app_ctx.g.xx), 再将取出来的值返回到视图

5. 视图函数处理完毕之后, 返回浏览器之前:
    - 在这个过程中, 会调用 pop() 方法:
        - ctx.pop() : 通过pop方法去到 local = Local() 中将 __storage__ = {线程号:{stack:[ctx]}} 中的 ctx删掉
        - app_ctx.pop() : 通过pop方法去到 local = Local() 中将 __storage__ = {线程号:{stack:[app_ctx]}} 中的 app_ctx删掉

5.5 在这个地方可能会执行 @app.after_request 等特殊装饰器

6. 返回给用户浏览器。

###  g 的理解 ###
概念:
    一次请求生命周期中生效的g
1. g 的生命周期:
    当有请求的时候, 就会为这个请求创建一个 g, 当这个请求结束的时候, 就会清除这个 g
        注: 有一个请求就创建一个 g, 且只能在同一个请求中使用
2.  多线程并不会影响 g, 因为每一个请求就会在 __storage__ 中创建一个唯一的线程号,
    这个线程号对应的字典中的app_ctx也是当前这个请求的, 是完全独立的内存空间。

原文地址:https://www.cnblogs.com/chaoqi/p/10508328.html

时间: 2024-08-28 16:05:48

python - Flask 上下文管理 流程的相关文章

Flask上下文管理、session原理和全局g对象

一.一些python的知识 1.偏函数 def add(x, y, z): print(x + y + z) # 原本的写法:x,y,z可以传任意数字 add(1,2,3) # 如果我要实现一个功能,这三个数中,其中一个数必须是3 # 我们就可以使用偏函数来帮着我们传参 from functools import partial # partial:给add这个函数固定传一个数字 3 new_add = partial(add, 3) # 因此新的函数只需要传2个参数 new_add(1,1)

谈一谈Python的上下文管理器

经常在Python代码中看到with语句,仔细分析下,会发现这个with语句功能好强,可以自动关闭资源.这个在Python中叫上下文管理器Context Manager.那我们要怎么用它,什么时候用它呢.这里我们就来聊一聊. 上下文管理器的作用 很多情况,当我们使用完一个资源后,我们需要手动的关闭掉它,比如操作文件,建立数据库连接等.但是,在使用资源的过程中,如果遇到异常,很可能错误被直接抛出,导致来不及关闭资源.所以在大部分程序语言里,我们使用"try-finally"语句来确保资源

python的上下文管理(contextlib)(2)

contextlib是一个Python模块,作用是提供更易用的上下文管理器. 编写 __enter__ 和 __exit__ 仍然很繁琐,因此Python的标准库 contextlib 提供了更简单的写法, 比如如下代码: from contextlib import contextmanager class Query(object): def __init__(self, name): self.name = name def query(self): print('Query info a

python使用上下文管理器实现sqlite3事务机制

如题,本文记录如何使用python上下文管理器的方式管理sqlite3的句柄创建和释放以及事务机制. 1.python上下文管理(with) python上下文管理(context),解决的是这样一类问题,在进入逻辑之前需要进行一些准备工作,在退出逻辑之前需要进行一些善后工作,上下文管理可以使得这种场景变得清晰和可控. with语句是python上下文管理的基本用法,例如读写文件 with open('filea', r) as f: f.readlines() file使用的就是上下文管理机制

Flask 上下文管理-- (session,request,current_app的传递)

Flask session,request,current_app的传递 1 flask的 request, session 和 current_app 都是 设置方式比较新颖 -- 通过上下文管理的方式实现的 每次请求进来app.run调用 call 方法, 创建 一个本地线程(唯一标识作为键) -- 然后把实例化的对象push到一个地方,在请求结束后返回的时候 pop 掉 local = { '标识':{'stack':[RequestContext(),]} } 2 补充 partial

flask上下文管理

flask的上下文管理分应用上下文和请求上下文: 官方文档里是说先理解应用上下文比较好,不过我还是觉得反过来,从请求上下文开始记录比较合适,所以这篇先记录请求上下文. 那么问题来了,什么才是请求上下文: 通俗点说,其实上下文就像一个容器,包含了很多你需要的信息 request和session都属于请求上下文 request 针对的是http请求作为对象 session针对的是更多是用户信息作为对象 上下文的结构 说到上下文这个概念的数据结构,这里需要先知道,他是运用了一个Stack的栈结构,也就

理解Python的上下文管理器

上下文管理器(context manager)是 Python 编程中的重要概念,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语法形式是with...as... 为了确保一些系统资源得以正确释放,我们经常会用到 try ... excepte ... finally 语句.如: try: f = open('somefile') for line in f: print(line) except Exception as e:

Python概念-上下文管理协议中的__enter__和__exit__

所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_val, exc_tb):当with运行结束之后触发此方法的运行 exc_type如果抛出异常,这里获取异常的类型 exc_val如果抛出异常,这里显示异常内容 exc_tb如果抛出异常,这里显示所在位置 代码示例:(以自己定义的Open类型做示例) 1 # 编辑者:闫龙 2 class Open: 3

Python进阶-----上下文管理协议(__enter__,__exit)

一.上下文管理协议 即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法 1.__enter__()会在with语句出现(实例化对象)时执行 2.__exit__()会在with语句的代码块实行完毕才会执行 1 class Open: 2 def __init__(self,name): 3 self.name = name 4 5 def __enter__(self): #在实例化打开文件时即触发,在with时触发 6 print(