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()的功能如下:

  1. 首先在栈里查找app_ctx,如果没有则创建;然后push app_ctx
  2. 其次_request_ctx_stack.push(self),就是push request_ctx
  3. 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都是有效的。

 

转载于:https://www.cnblogs.com/wodeboke-y/p/11442872.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值