flask上下文
Posted wodeboke-y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask上下文相关的知识,希望对你有一定的参考价值。
flask上下文
1. flask上下文
1.1. 上下文使用-请求上下文
先看一下flask是怎么使用上下文的
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)
这里有三句,分别是生成对象,入栈,出栈
ctx = self.request_context(environ)
ctx.push()
ctx.auto_pop(error)
看一下request_context,很简单,返回RequestContext(self, environ)对象,它支持push,pop,也可以使用with
def request_context(self, environ):
"""Create a :class:`~flask.ctx.RequestContext` representing a
WSGI environment. Use a ``with`` block to push the context,
which will make :data:`request` point at this request.
"""
return RequestContext(self, environ)
1.1.1. ctx.push()
ctx.push()的功能如下:
- 首先在栈里查找app_ctx,如果没有则创建;然后push app_ctx
- 其次_request_ctx_stack.push(self),就是push request_ctx
- session获取或创建,保存到ctx.session,也就是请求上下文类的session属性
1.1.2. ctx.auto_pop(error)
与ctx.push()类似,不过顺序是反过来的。
save session
pop request ctx
pop app ctx
2. 原理及实现
flask使用了两个上下文类, 请求上下文和应用上下文。
class RequestContext(object):
"""The
request context contains all request relevant information. It is
created at the beginning of the
request and pushed to the
`_request_ctx_stack` and removed at
the end of it. It will create the
URL adapter and request object for
the WSGI environment provided.
class AppContext(object):
"""The
application context binds an application object implicitly
to the current thread or greenlet,
similar to how the
:class:`RequestContext` binds request
information. The application
context is also implicitly created if
a request context is created
but the application is not on top of
the individual application
context.
"""
与threading.local类似,实质都是操纵两个全局变量字典,但在类的行为上实现了连接与线程级别的隔离。
上下文类实际上操纵的是下面这些类
flask.global.py
# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, ‘request‘))
session = LocalProxy(partial(_lookup_req_object, ‘session‘))
g = LocalProxy(partial(_lookup_app_object, ‘g‘))
2.1. 关于g
g的定义在flask.globals.py中
def _lookup_app_object(name):
top = _app_ctx_stack.top
if top is None:
raise RuntimeError(_app_ctx_err_msg)
return getattr(top, name)
g = LocalProxy(partial(_lookup_app_object, ‘g‘))
g相当于指向当前应用上下文的top,它同样对于连接及线程是隔离的,问题是为什么要写这么复杂,不是非常理解。
# a simple page that says hello
@app.route(‘/‘)
def index():
g.va = 87
print(g, type(g))
func_g()
return ‘Index.‘
def func_g():
print(‘g.va=‘, g.va)
作用范围:只要是在一次请求的应用上下文中,g都是有效的。
以上是关于flask上下文的主要内容,如果未能解决你的问题,请参考以下文章