作为该线程中信息的附录:我也flask.g
对它的行为感到困惑,但是一些快速测试帮助我弄清了它。这是我尝试过的方法:
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
print('in app context, before first request context')
print('setting g.foo to abc')
g.foo = 'abc'
print('g.foo should be abc, is: {0}'.format(g.foo))
with app.test_request_context():
print('in first request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
print('setting g.foo to xyz')
g.foo = 'xyz'
print('g.foo should be xyz, is: {0}'.format(g.foo))
print('in app context, after first request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
with app.test_request_context():
print('in second request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
print('setting g.foo to pqr')
g.foo = 'pqr'
print('g.foo should be pqr, is: {0}'.format(g.foo))
print('in app context, after second request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
这是它提供的输出:
in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc
in first request context
g.foo should be abc, is: abc
setting g.foo to xyz
g.foo should be xyz, is: xyz
in app context, after first request context
g.foo should be abc, is: xyz
in second request context
g.foo should be abc, is: xyz
setting g.foo to pqr
g.foo should be pqr, is: pqr
in app context, after second request context
g.foo should be abc, is: pqr
正如Y4Kman所说的那样,“每个请求都推送一个新的应用程序上下文”。而随着烧瓶文档说,应用程序上下文“将不被请求之间共享”。现在,尚未明确说明的内容(尽管我猜想这是这些语句的隐含内容),而我的测试清楚地表明,您永远不应明确创建嵌套在一个应用程序上下文中的多个请求上下文,因为flask.g
(和co)没有它具有任何神奇的功能,使其可以在上下文的两个不同“级别”中起作用,并且在应用程序和请求级别独立存在不同的状态。
现实情况是,“应用程序上下文”可能app.app_context()
是一个颇具误导性的名称,因为它是每个请求上下文,与“请求上下文”完全相同。将其视为“请求上下文精简版”,仅在需要一些通常需要请求上下文的变量但不需要访问任何请求对象的情况下才需要(例如,在数据库中运行批处理DB操作时)外壳脚本)。如果您尝试将应用程序上下文扩展为包含多个请求上下文,那么您将遇到麻烦。因此,您应该在Flask的上下文中编写如下代码,而不是上面的测试:
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
print('in app context, before first request context')
print('setting g.foo to abc')
g.foo = 'abc'
print('g.foo should be abc, is: {0}'.format(g.foo))
with app.test_request_context():
print('in first request context')
print('g.foo should be None, is: {0}'.format(g.get('foo')))
print('setting g.foo to xyz')
g.foo = 'xyz'
print('g.foo should be xyz, is: {0}'.format(g.foo))
with app.test_request_context():
print('in second request context')
print('g.foo should be None, is: {0}'.format(g.get('foo')))
print('setting g.foo to pqr')
g.foo = 'pqr'
print('g.foo should be pqr, is: {0}'.format(g.foo))
这将产生预期的结果:
in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc
in first request context
g.foo should be None, is: None
setting g.foo to xyz
g.foo should be xyz, is: xyz
in second request context
g.foo should be None, is: None
setting g.foo to pqr
g.foo should be pqr, is: pqr
g
为0.10,否则听起来很多代码可能会开始开发一些de回的bug。