flask的上下文管理
首先我们知道项目启动执行了app.run()方法~~调用了werkzeug的run_simple()方法~
run_simple(host, port, self, **options) 这时候的self就是我们的app~
run_simple会执行self(),也就是app(), 那么app = Flask() 所以会走Flask的__call__方法~
上下文管理一:

然后通过RequestContext对我们的request,session进行封装

进入RequestContext:

来到ctx.push方法:


其实是调用LocalStack中的push方法:

进入这个LocalStack类,这个个self就是我们传进去的ctx

这个LocalStack类的init方法:


就是给我们这个Local类初始化了两个属性~~__storage__ = {} __ident_func__ = get_ident
再看LocalStack的push方法做了什么:

rv请求刚开始为空,然后就变为这种结构:{‘stack’: [ ]},然后,把我们的ctx对象放入列表中。
上下文管理二
在我们的视图函数中上面那种拿request的方法太费劲了~我们需要简单一点的拿到request~~
那么我们导入的request跟我们上面拿到的request一定是一样的~~那导入的这个request做了什么呢

reqeust是LocalProxy这个类的实例化对象~参数是一个偏函数
那当我们调用request.method 等方法的时候走的是LocalProxy这个类的__getattr__方法

这里的_get_current_object()相当于我们偏函数的执行


到这里,就跟我们上面的取值方式一样了,也就是说通过LocalStack方法去Local中去ctx对象
然后通过getattr 找到ctx.request
也就是说这个LocalProxy就是一个帮助我们取值的代理, 让我们的取值变的更加简单。
这个代理通过偏函数来绑定参数
ctx中封装了request,以及session~只不过到这里我们的session依然是空的。
session的实现原理
接下来,往RequestContext的push方法继续走:

这里的open_session方法是SecureCookieSessionInterface()中的open_session,

也就是说~请求进来把ctx放入Local中后~~从前端解密了cookie~然后把解密数据好的数据给了self.session
这个session_class是session_class = SecureCookieSession,

它继承了字典,所以我们可以直接session['k1'] = 123进行赋值,调用了字典的__setitem__方法。

然后继续走:




我们可以看到, session的原理是就是:
从cookie中获取数据,解密存入session。请求走的时候,就把session中数据取出来,加密, 给响应设置cookie。
那么我们平时在视图中设置删除session的值,原来跟request是一样的,就是通过代理去修改Local中的数据。
上下文管理三:应用上下文

这个app_context是AppContext,他封装了app和g。
也就是说, 我们请求上下文和应用上下文分别建立了两个Local对象。
全局g对象
g和全局对象有什么区别~~
1--我们知道请求进来会为每个请求在Local中建立一个独立空间,
也就是在应用上下文的Local对象中建立了一个g对象,当请求走的时候就会删除,
所以g的生命周期是请求进来到走。
2--session不一样的是保存在cookie中,所以下次请求来的时候cookie带来了。
3--全局变量是在项目启动创建的,无论多少请求进来都可以访问全局变量。
我们的g对象一般情况用于before_request中设置值~只为这一次请求建立全局变量。
注意:如果不通过before_request来设置g值,重定向后,在其他视图函数是不可能访问到这个g值的。因为g的生命周期,只有一次请求的开始到结束。

浙公网安备 33010602011771号