В качестве дополнения к информации в этой теме: меня тоже немного смутило поведение 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 , контекст приложения «не будет разделен между запросами». Теперь, что не было явно указано (хотя я предполагаю, что это подразумевается из этих утверждений), и что ясно показывает мое тестирование, это то, что вы никогда не должны явно создавать несколько контекстов запроса, вложенных в один контекст приложения, потому что 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, иначе может показаться, что во многих кодах могут появиться некоторые ошибочные ошибки.