Ich habe gesehen, dass dies g
in Flask 0.10 vom Anforderungskontext in den App-Kontext verschoben wird, was mich über die beabsichtigte Verwendung von verwirrt hat g
.
Mein Verständnis (für Flask 0.9) ist das:
g
lebt im Anforderungskontext, dh wird beim Start der Anforderungen neu erstellt und ist bis zum Ende verfügbarg
soll als "Anfragetafel" verwendet werden, an der ich für die Dauer der Anforderung relevante Informationen einfügen kann (dh am Anfang der Anforderung ein Flag setzen und am Ende bearbeiten, möglicherweise von einembefore_request
/after_request
Paar).g
Kann und sollte zusätzlich zum Halten des Status auf Anforderungsebene für das Ressourcenmanagement verwendet werden, dh zum Halten von Datenbankverbindungen usw.
Welche dieser Sätze sind in Flask 0.10 nicht mehr wahr? Kann mich jemand auf eine Ressource verweisen, in der die Gründe für die Änderung besprochen werden? Was soll ich als "Request Blackboard" in Flask 0.10 verwenden - sollte ich meinen eigenen app- / erweiterungsspezifischen threadlokalen Proxy erstellen und in den Kontextstapel verschieben before_request
? Was bringt das Ressourcenmanagement im Anwendungskontext, wenn meine Anwendung lange lebt (nicht wie eine Anforderung) und die Ressourcen daher niemals freigegeben werden?
g
in 0.10 ersetzt werden soll. Andernfalls klingt es so, als würde viel Code einige abwegige Fehler entwickeln.flask.g
. Speakerdeck.com/mitsuhiko/advanced-flask-patterns-1Antworten:
Advanced Flask Patterns , wie von Markus verlinkt , erklärt einige der Änderungen
g
in 0.10:g
lebt jetzt im Anwendungskontext.g
weiterhin Flags pro Anforderung gesetzt werden können, ohne dass der Code geändert werden muss.teardown_request
Aufruf geöffnet . (Armins Präsentation erklärt dies, weil Dinge wie das Erstellen von DB-Verbindungen Aufgaben sind, die die Umgebung für die Anforderung einrichten und nicht inbefore_request
und behandelt werden sollten.after_request
)quelle
app_ctx is None or app_ctx.app != self.app
False angezeigt wird, scheint der alte Anwendungskontext wiederverwendet zu werden. Dies scheint nicht richtig zu sein, da der Anwendungskontext "nicht zwischen Anforderungen geteilt wird" ...app.app_context()
? Wenn ja, sollte beachtet werden, dass beiapp_context()
jedem Aufruf ein neuer Anwendungskontext instanziiert wird - ein Kontext wird nie wiederverwendet.app_ctx is not None and app_ctx.app == self.app
, wird dieapp_ctx = self.app.app_context()
Zeile nicht ausgeführt. Nurself._implicit_app_ctx_stack.append(None)
wird in diesem Fall ausgeführt.RequestContext
wird gedrückt, also wird nur einerAppContext
gedrückt. Wenn der Debug-Modus aktiviert ist und eine Anforderung fehlschlägt, speichert Flask den Kontext , sodass er mit dem Debugger verwendet werden kann .None
wird an das angehängt._app_ctx_stack
Wenn die Anforderung abgerissen wird, weiß sie, dass dasAppContext
gerade noch nicht angezeigt wird. Dasselbe passiert mit dem Testclient, der den Kontext beibehält, damit er überprüft werden kann.Als Ergänzung zu den Informationen in diesem Thread: Ich war auch ein bisschen verwirrt über das Verhalten von
flask.g
, aber einige schnelle Tests haben mir geholfen, dies zu klären. Folgendes habe ich ausprobiert:Und hier ist die Ausgabe, die es gibt:
Wie der Y4Kman oben sagte: "Jede Anfrage drückt einen neuen Anwendungskontext". Und wie in den Flask-Dokumenten angegeben, wird der Anwendungskontext "nicht zwischen Anforderungen geteilt". Was jetzt nicht explizit angegeben wurde (obwohl ich denke, dass dies aus diesen Aussagen hervorgeht), und was meine Tests deutlich zeigen, ist, dass Sie niemals explizit mehrere Anforderungskontexte erstellen sollten , die in einem Anwendungskontext verschachtelt sind, weil
flask.g
(und co) dies nicht tun. Es gibt keine Magie, durch die es in den zwei verschiedenen "Kontextebenen" funktioniert, wobei verschiedene Zustände unabhängig voneinander auf Anwendungs- und Anforderungsebene existieren.Die Realität ist, dass "Anwendungskontext" möglicherweise ein ziemlich irreführender Name ist, da
app.app_context()
es sich um einen Kontext pro Anforderung handelt , der genau dem "Anforderungskontext" entspricht . Stellen Sie sich das als "Anforderungskontext-Lite" vor, der nur erforderlich ist, wenn Sie einige der Variablen benötigen, für die normalerweise ein Anforderungskontext erforderlich ist, Sie jedoch keinen Zugriff auf ein Anforderungsobjekt benötigen (z. B. wenn Sie Batch-DB-Vorgänge in a ausführen Shell-Skript). Wenn Sie versuchen, den Anwendungskontext auf mehr als einen Anforderungskontext zu erweitern, fragen Sie nach Problemen. Anstelle meines obigen Tests sollten Sie stattdessen Code wie diesen mit Flask's Kontexten schreiben:Welches wird die erwarteten Ergebnisse geben:
quelle