flask源码剖析之上下文全局变量
来源:互联网 发布:dnf安徒恩优化补丁 编辑:程序博客网 时间:2024/05/20 15:11
flask有四个线程级的全局变量,两个是程序上下文变量:current_app和g,另外两个是请求上下文变量:request和session.
这四个变量只有从flask.globals中导入才可以使用,即
from flask import current_app
from flask import g
from flask import request
from flask import session
但是使用不意味着有效,要想有效,导入后还要再push程序上下文变量和请求上下文变量:
1)利用flask.app中的app.app_context()或app.request_context()方法建立AppContext(app)实例或RequestContext(...)实例;
app_ctx = app.app_context()
request_ctx = app.request_context(...)
def app_context(self): """Binds the application only. For as long as the application is bound to the current context the :data:`flask.current_app` points to that application. An application context is automatically created when a request context is pushed if necessary. Example usage:: with app.app_context(): ... .. versionadded:: 0.9 """ return AppContext(self) def request_context(self, environ): """Creates a :class:`~flask.ctx.RequestContext` from the given environment and binds it to the current context. This must be used in combination with the `with` statement because the request is only bound to the current context for the duration of the `with` block. Example usage:: with app.request_context(environ): do_something_with(request) The object returned can also be used without the `with` statement which is useful for working in the shell. The example above is doing exactly the same as this code:: ctx = app.request_context(environ) ctx.push() try: do_something_with(request) finally: ctx.pop() .. versionchanged:: 0.3 Added support for non-with statement usage and `with` statement is now passed the ctx object. :param environ: a WSGI environment """ return RequestContext(self, environ)
2)调用1)中建立的实例相应的push()方法——flask.ctx中;
app_ctx.push( )
or request_ctx.push( ) ???这个好像不需要???P12
确实不需要,因为这是系统自动帮我们完成的!!!!具体参见文章Flask request,g,session的实现原理
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. """ def __init__(self, app): self.app = app self.url_adapter = app.create_url_adapter(None) self.g = app.app_ctx_globals_class() # Like request context, app contexts can be pushed multiple times # but there a basic "refcount" is enough to track them. self._refcnt = 0 def push(self): """Binds the app context to the current context.""" self._refcnt += 1 _app_ctx_stack.push(self) appcontext_pushed.send(self.app) ......
3)2)中的push()方法实际上就是利用LocalStack()的实例_app_ctx_stack或_request_ctx_stack的push()方法——入栈。因此我们可以使用flask创建n个web app,而不会错乱。
一个web app有很多个request和session信息,使用_request_ctx_stack保存。
# -*- coding: utf-8 -*-""" flask.globals ~~~~~~~~~~~~~ Defines all the global objects that are proxies to the current active context. :copyright: (c) 2011 by Armin Ronacher. :license: BSD, see LICENSE for more details."""from functools import partialfrom werkzeug.local import LocalStack, LocalProxydef _lookup_req_object(name): top = _request_ctx_stack.top if top is None: raise RuntimeError('working outside of request context') return getattr(top, name)def _lookup_app_object(name): top = _app_ctx_stack.top if top is None: raise RuntimeError('working outside of application context') return getattr(top, name)def _find_app(): top = _app_ctx_stack.top if top is None: raise RuntimeError('working outside of application context') return top.app# 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'))
4)因此,所谓的app_ctx.push()实质上是落实在LocalStack().push()即_app_ctx_stack.push()之上的!
可参考文章Flask request,g,session的实现原理
- flask源码剖析之上下文全局变量
- Flask源码剖析
- Android之上下文菜单
- flask源码剖析之工作流程
- .NET组件程序设计之上下文
- 第十五章之上下文菜单
- hibernate之上下文初始化失败
- flask 上下文全局变量
- 文法系列之上下文无关语法简介
- android基础学习之上下文菜单
- Android之上下文菜单(ContextMenu)
- java 并发编程之上下文切换
- ucos-iii学习之上下文切换
- C# 参考之上下文关键字:get、set、value (ZT)
- linux进程管理之上下文切换(context switching)
- Nucleus Task切换及中断之上下文保存
- Android用户界面菜单之上下文菜单(Context Menu)
- 一起学android之上下文菜单创建(5)
- 南邮JAVA程序设计实验1 综合图形界面程序设计
- 如何解决XML5619: 文档语法不正确
- uc/os-ii消息邮箱
- sqlServer DateTime数据类型的格式转换
- 8String to Integer (atoi)
- flask源码剖析之上下文全局变量
- spring mvc,在controller中获取属性文件的值
- 【Effective Objective-C 2.0读书笔记】第三章:接口和API设计
- Autofac官方文档翻译——(二)组件注册(未完)
- 南邮JAVA程序设计实验2 小应用程序Applet设计
- Factory Method模式是简化版的Abstract Factory吗?
- WebStorm9配置supervisor热部署NodeJS
- Android AdapterView以及子类
- iOS 沙盒目录下的文件的读写。