我想在我的flask
应用程序中保存缓存字典。
据我了解,Application Context,特别是flask.g object应该用于此。
建立:
import flask as f
app = f.Flask(__name__)
如果我这样做:
with app.app_context():
f.g.foo = "bar"
print f.g.foo
它打印bar
。
继续以下内容:
with app.app_context():
print f.g.foo
AttributeError: '_AppCtxGlobals' object has no attribute 'foo'
我不明白,文档根本没有帮助。如果我正确阅读它们,应该保留状态。
我的另一个想法是简单地使用模块范围的变量:
cache = {}
def some_function():
cache['foo'] = "bar"
但似乎每次请求都会重置这些内容。
怎么做到这一点?
编辑:Flask 10.1
根据你的问题,我认为你对“全球”的定义感到困惑。
在Flask设置库中,您有一个Flask服务器,其中包含多个线程,并且可能有多个进程处理请求。假设您有一个像“itemlist = []”这样的股票全局变量,并且您希望在每个请求中继续添加它 - 比如每次有人向端点发出POST请求时。这在理论和实践中是完全可能的。这也是一个非常糟糕的主意。
问题是你无法轻易控制哪些线程和进程“赢” - 列表可能以一个非常糟糕的顺序出现,或者完全被破坏。所以现在你需要谈论锁,互斥和其他原语。这很难,也很烦人。
您应该将Web服务器本身保持为尽可能无状态。每个请求应该是完全独立的,不能在服务器中共享任何状态。相反,使用将为您处理状态的数据库或缓存层。这似乎更复杂,但实际上更简单。以SQLite为例;这很简单。
要解决'flask.g'对象,这是一个基于每个请求的全局对象。
http://flask.pocoo.org/docs/api/#flask.g
它在请求之间“擦除”,不能用于在它们之间共享状态。
这条线
with app.app_context():
f.g.foo = "bar"
由于您使用的是“with”关键字,因此一旦执行此循环,它将调用AppContext类的__exit__
方法。见this。所以'foo'一旦完成就会弹出。这就是为什么你没有再次使用它。您可以尝试:
ctx = app.app_context()
f.g.foo = 'bar'
ctx.push()
在您调用以下内容之前,g.foo应该可用
ctx.pop()
我不知道你是否想要将它用于缓存目的。
我已经做了一些类似于我的“模块范围变量”的想法,我在烧瓶服务器中使用它来集成两个软件,我知道我将只有一个同时“用户”(作为发送者软件) 。
我的app.py看起来像这样:
from flask import Flask
from flask.json import jsonify
app = Flask(__name__)
cache = {}
@app.route("/create")
def create():
cache['foo'] = 0
return jsonify(cache['foo'])
@app.route("/increment")
def increment():
cache['foo'] = cache['foo'] + 1
return jsonify(cache['foo'])
@app.route("/read")
def read():
return jsonify(cache['foo'])
if __name__ == '__main__':
app.run()
你可以像这样测试它:
import requests
print(requests.get('http://127.0.0.1:5000/create').json())
print(requests.get('http://127.0.0.1:5000/increment').json())
print(requests.get('http://127.0.0.1:5000/increment').json())
print(requests.get('http://127.0.0.1:5000/read').json())
print(requests.get('http://127.0.0.1:5000/increment').json())
print(requests.get('http://127.0.0.1:5000/create').json())
print(requests.get('http://127.0.0.1:5000/read').json())
输出:
0
1
2
2
3
0
0
请谨慎使用,因为我希望这在不适当的多用户Web服务器环境中不起作用。