Я видел, что g
в Flask 0.10 из контекста запроса перейдет контекст приложения, что привело меня в замешательство относительно предполагаемого использования g
.
Мое понимание (для Flask 0.9) заключается в следующем:
g
живет в контексте запроса, т. е. создается заново при запуске запроса и доступен до его окончанияg
предназначен для использования в качестве «доски запросов», где я могу поместить вещи, относящиеся к продолжительности запроса (то есть установить флаг в начале запроса и обработать его в конце, возможно, изbefore_request
/after_request
пары)- в дополнение к хранению уровня запроса,
g
может и должен использоваться для управления ресурсами, т. е. для удержания соединений с базой данных и т. д.
Какие из этих предложений больше не соответствуют действительности в Flask 0.10? Может кто-нибудь указать мне на ресурс, обсуждающий причины изменений? Что я должен использовать в качестве «доски запросов» в Flask 0.10 - я должен создать свой собственный локальный прокси-сервер для конкретного приложения / расширения и поместить его в стек контекста before_request
? Какой смысл управления ресурсами в контексте приложения, если мое приложение живет долго (не как запрос) и, следовательно, ресурсы никогда не освобождаются?
g
в 0.10, иначе может показаться, что во многих кодах могут появиться некоторые ошибочные ошибки.flask.g
. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1Ответы:
Усовершенствованные шаблоны колб , связанные с Маркусом , объясняют некоторые изменения
g
в 0.10:g
теперь живет в контексте приложения.g
все еще может использоваться для установки флагов для запроса без изменения кода.teardown_request
. (Презентация Армина объясняет это происходит потому , что такие вещи , как создание соединений БДА являются задачами , которые настройка среды для запроса, и не должна быть обработана внутриbefore_request
иafter_request
)источник
app_ctx is None or app_ctx.app != self.app
False, старый контекст приложения, кажется, используется повторно? Это кажется неправильным, поскольку контекст приложения «не будет разделен между запросами» ...app.app_context()
? Если это так, следует отметить,app_context()
что каждый новый вызов создает новый контекст приложения - он никогда не использует контекст повторно.app_ctx is not None and app_ctx.app == self.app
, тоapp_ctx = self.app.app_context()
строка не выполняется; толькоself._implicit_app_ctx_stack.append(None)
выполняется в этом случае.RequestContext
, поэтому толкается только одинAppContext
. Но если включен режим отладки и запрос не выполняется, Flask сохраняет контекст , поэтому его можно использовать с отладчиком .None
добавляется к_app_ctx_stack
, поэтому, когда запрос сносится, он не знает, пока неAppContext
появится. То же самое происходит с тестовым клиентом, который сохраняет контекст, чтобы его можно было проверить.В качестве дополнения к информации в этой теме: меня тоже немного смутило поведение
flask.g
, но некоторое быстрое тестирование помогло мне прояснить это. Вот что я опробовал:И вот результат, который это дает:
Как сказал выше Y4Kman: «Каждый запрос выдвигает новый контекст приложения». И, как говорят в документации Flask , контекст приложения «не будет разделен между запросами». Теперь, что не было явно указано (хотя я предполагаю, что это подразумевается из этих утверждений), и что ясно показывает мое тестирование, это то, что вы никогда не должны явно создавать несколько контекстов запроса, вложенных в один контекст приложения, потому что
flask.g
(и co) не ' У него нет никакого волшебства, благодаря которому он функционирует на двух разных «уровнях» контекста, причем разные состояния существуют независимо на уровнях приложения и запроса.Реальность такова , что «контекст приложения» потенциально весьма вводит в заблуждение название, потому что
app.app_context()
это за запроса контекста , точно так же , как «контекст запроса» . Думайте об этом как о «запросе контекста lite», необходимом только в том случае, если вам нужны некоторые переменные, для которых обычно требуется контекст запроса, но вам не нужен доступ к какому-либо объекту запроса (например, при выполнении пакетных операций с БД в сценарий оболочки). Если вы попытаетесь расширить контекст приложения, чтобы охватить более одного контекста запроса, у вас возникнут проблемы. Итак, вместо моего теста выше, вы должны вместо этого написать код, подобный этому, с контекстами Flask:Который даст ожидаемые результаты:
источник