Як доповнення до інформації в цій темі: Я теж трохи збентежився поведінкою 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
Як сказав theY4Kman вище, "Кожен запит підштовхує новий контекст програми". І як кажуть документи Flask , контекст програми "не буде розподілений між запитами". Тепер те, що не було чітко зазначено (хоча я думаю, що це випливає з цих тверджень), і що моє тестування чітко показує, - це те, що ви ніколи не повинні явно створювати кілька контекстів запитів, вкладених в один контекст програми, тому що flask.g
(і co) не ' не мати будь-якої магії, за якої вона функціонує на двох різних "рівнях" контексту, причому різні стани існують незалежно на рівні заявки та запиту.
Реальність така , що «контекст додатки» потенційно дуже вводить в оману назва, тому що app.app_context()
це за запиту контексту , точно так же , як «контекст запиту» . Розгляньте це як "контекст запиту Lite", необхідний лише в тому випадку, коли вам потрібні деякі змінні, які зазвичай вимагають контексту запиту, але вам не потрібен доступ до будь-якого об'єкта запиту (наприклад, під час виконання пакетних операцій БД у скрипт оболонки). Якщо ви спробуєте розширити контекст програми, щоб охопити більше одного контексту запиту, ви задаєте проблеми. Отже, замість мого тесту вище, замість цього слід писати такий код із контекстами 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, інакше це звучить, як багато коду може почати розробляти деякі хибні помилки.