I saw que g
vai passar a partir do contexto de solicitação ao contexto aplicativo na garrafa de 0,10, o que me fez confuso sobre o uso pretendido g
.
Meu entendimento (para o Flask 0.9) é que:
g
vive no contexto da solicitação, ou seja, criado novamente quando a solicitação é iniciada e disponível até o términog
destina-se a ser usado como um "quadro de solicitação", onde eu posso colocar coisas relevantes para a duração da solicitação (ou seja, definir uma sinalização no início da solicitação e manipulá-la no final, possivelmente de umbefore_request
/after_request
par)- além de manter o estado de nível de solicitação,
g
pode e deve ser usado para gerenciamento de recursos, ou seja, manter conexões de banco de dados, etc.
Quais dessas frases não são mais verdadeiras no Flask 0.10? Alguém pode me indicar um recurso que discuta os motivos da mudança? O que devo usar como um "quadro de solicitação" no Flask 0.10 - devo criar meu próprio proxy local de segmento específico de aplicativo / extensão e enviá-lo para a pilha de contexto before_request
? Qual é o sentido do gerenciamento de recursos no contexto do aplicativo, se meu aplicativo permanecer por um longo tempo (não como uma solicitação) e, assim, os recursos nunca forem liberados?
g
na 0.10, caso contrário, parece que muito código pode começar a desenvolver alguns erros desonestos.flask.g
. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1 #Respostas:
O Advanced Flask Patterns , conforme vinculado por Markus , explica algumas das alterações
g
no 0.10:g
agora vive no contexto do aplicativo.g
ainda pode ser usado para definir sinalizadores por solicitação sem alterar o código.teardown_request
é chamado. (A apresentação de Armin explica isso porque coisas como criar conexões com o banco de dados são tarefas que configuram o ambiente para a solicitação e não devem ser tratadas internamentebefore_request
eafter_request
)fonte
app_ctx is None or app_ctx.app != self.app
é False, o contexto antigo do aplicativo parece ser reutilizado? Este não parece ser certo, uma vez que o contexto de aplicação "não será compartilhada entre os pedidos" ...app.app_context()
? Nesse caso, deve-se notar queapp_context()
instancia um novo contexto de aplicativo a cada chamada - nunca reutiliza um contexto.app_ctx is not None and app_ctx.app == self.app
, aapp_ctx = self.app.app_context()
linha não é executada; somenteself._implicit_app_ctx_stack.append(None)
é executado neste caso.RequestContext
é empurrado, então apenas umAppContext
é empurrado. Mas se o modo de depuração estiver ativado e uma solicitação falhar, o Flask salva o contexto , para que possa ser usado com o depurador .None
é anexado ao_app_ctx_stack
, portanto, quando a solicitação está sendo cortada, ele sabe que ainda não deve aparecerAppContext
. O mesmo ocorre com o cliente de teste, que mantém o contexto, para que possa ser inspecionado.Como um adendo às informações neste tópico: Também fiquei um pouco confuso com o comportamento
flask.g
, mas alguns testes rápidos me ajudaram a esclarecê-lo. Aqui está o que eu tentei:E aqui está o resultado que ele fornece:
Como o Y4Kman disse acima, "Toda solicitação impulsiona um novo contexto de aplicativo". E, como dizem os documentos do Flask , o contexto do aplicativo "não será compartilhado entre solicitações". Agora, o que não foi declarado explicitamente (embora eu ache que esteja implícito nessas declarações) e o que meus testes mostram claramente é que você nunca deve criar explicitamente vários contextos de solicitação aninhados dentro de um contexto de aplicativo, porque
flask.g
(e co) não ' não possui mágica em que funcione nos dois "níveis" diferentes de contexto, com estados diferentes existindo independentemente nos níveis de aplicação e solicitação.A realidade é que "contexto de aplicativo" é potencialmente um nome enganoso, porque
app.app_context()
é um contexto por solicitação , exatamente o mesmo que "contexto de solicitação" . Pense nisso como uma "lista de contexto de solicitação", necessária apenas no caso em que você precisa de algumas das variáveis que normalmente requerem um contexto de solicitação, mas não precisa de acesso a nenhum objeto de solicitação (por exemplo, ao executar operações de banco de dados em lote em um shell script). Se você tentar estender o contexto do aplicativo para abranger mais de um contexto de solicitação, estará solicitando problemas. Portanto, em vez do meu teste acima, você deve escrever um código como este nos contextos do Flask:O que dará os resultados esperados:
fonte