应用上下文

来源:互联网 发布:宋徽宗 知乎 编辑:程序博客网 时间:2024/06/05 12:12
应用上下文Flask背后的设计理念之一就是,代码在执行时会处于两种状态(states)。当Flask对象被实例化后在模块层次上应用便开始隐式地处于应用配置状态。一直到第一个请求还是到达这种状态才隐式地结束。当应用处于这个状态的时候,你可以认为下面的假设是成立的:1 - 程序员可以安全地修改应用对象2 - 目前还没有处理任何请求3 - 你必须得有一个指向应用对象的引用来修改它。相反,到了第二个状态,在处理请求时,有一些其他的规则:1 - 当一个请求激活时,上下文的本地对象(比如flask.request)指向当前的请求2 - 你可以在任何时间里使用任何代码与这些对象通信应用上下文的作用应用上下文存在的主要原因是,在过去,请求上下文被附加了一堆函数,但是又没有什么好的解决方案。因为Flask设计的支柱之一是你可以在一个Python进程中拥有多个应用。那么代码如何找到'正确的'应用?在过去,我们推荐显式地传递应用,但是这会让我们在使用不是以这种理念设计的库的时候遇到问题。解决上述问题的常用方法是使用后边将会提到的current_app代理对象,它被绑定到当前请求的应用的引用。既然无论如何在没有请求时创建一个这样的请求上下文是一个没有必要啊的昂贵操作,应用上下文就被引入了。创建应用上下文有两种方式创建应用上下文。第一种是隐式地:无论何时当一个请求上下文被压栈时,如果有必要的话一个应用上下文会一起被创建。由于这个原因,你可以忽略应用上下文的存在,除非你需要它。第二种是显式地调用app_context()方法:from flask import Flask,current_appapp = Flask(__name__)with app.app_context():print current_app.name应用上下文局部变量应用上下文会在必要时被创建和销毁。它不会在线程间移动,并且也不会再通的请求之前共享。正因为如此,它是一个存储数据库连接信息或是别的东西的最佳位置。内部的栈对象叫做flask._app_ctx_stack。扩展可以在最顶层自由的存储额外信息,想象一个他们用一个充分独特的名字在哪里存储信息,而不是flask.g对象里,flask.g是留给用户的代码用的。上下文用法上下文的一个典型应用场景就是用来缓存一些我们需要在发生请求之前或者要是用的资源。举个例子,比如数据库连接。当我们在应用上下文中来存储东西的时候你得选择一个唯一的名字,这是因为应用上下文为Flask应用和扩展所共享。最常见的应用就是把资源的管理分成如下两个部分:1,一个缓存在上下文中的隐式资源2,当上下文被销毁时重新分配基础资源通常来讲,这将会有一个get_X()函数来创建资源X,如果它还不存在的话。存在的话,就直接返回它。另外还会有一个teardown_X()的回调函数用于销毁资源X。连接数据库示例import sqlite3from flask import Flaskdef get_db():db = getattr(g,'_database',None)if db is None:db = g._database = connect_to_database()return db@app.teardown_appcontextdef teardown_db(exception):db = getattr(g,'_database',None)if db is not None:db.close()当get_db()这个函数第一次被调用的时候,数据库就已经建立了。为了使看起来更隐式一点,我们可以使用LocalProxy这个类:from werkzueg.local import LocalProxy db = LocalProxy(db)这样的话用户就可以直接通过访问db来获取数据句柄了,db已经在内部完成了对get_db()的调用。

原创粉丝点击