in diesem Thread zu den Informationen Als Nachtrag: Ich war ein wenig verwirrt durch das Verhalten von flask.g
, aber einige schnelle Tests haben mir geholfen, es zu klären. Hier ist, was ich ausprobiert:
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))
Und hier ist der Ausgang, die es gibt:
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
Wie theY4Kman oben gesagt: „Jede Anfrage schiebt einen neuen Anwendungskontext“. Und as the Flask docs say, der Anwendungskontext "wird nicht zwischen Anfragen geteilt". Nun, was nicht explizit gesagt wurde (obwohl ich denke, dass es aus diesen Aussagen impliziert ist), und was meine Tests deutlich zeigen, ist, dass Sie niemals explizit mehrere Anforderungskontexte verschachtelt in einem Anwendungskontext erstellen, weil flask.g
(und co) hat keine Magie, wodurch es in den zwei verschiedenen "Ebenen" des Kontextes funktioniert, mit verschiedenen Zuständen, die unabhängig auf den Anwendungs- und Anfrageebenen existieren.
Die Realität ist, dass „Anwendungskontext“ ist möglicherweise ein ziemlich irreführend Namen, weil app.app_context()
ist ein pro-Anforderungskontext, genau das gleiche wie der „Anforderungskontext“. Stellen Sie es sich als "request context lite" vor, nur für den Fall, dass Sie einige der Variablen benötigen, die normalerweise einen Anforderungskontext benötigen, aber keinen Zugriff auf ein Anforderungsobjekt benötigen (z. B. beim Ausführen von Batch-DB-Operationen in einem Shell-Skript). Wenn Sie versuchen, den Anwendungskontext auf mehrere Anforderungskontexte auszudehnen, werden Sie nach Problemen gefragt. Also, anstatt mein Test oben, sollten Sie stattdessen Code wie folgt mit Kontexten der Flask schreiben:
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))
die erwarteten Ergebnisse geben wird.
Ich stimme zu, das ist eine ziemlich merkwürdige Veränderung. Hoffentlich implementiert mitsuhiko eine Art Request-Context-Objekt, um 'g' in 0.10 zu ersetzen, sonst hört es sich so an, als würde viel Code mit der Entwicklung einiger hinterhältiger Bugs beginnen. – Anorov
FWIW, Armin Ronacher (Autor von Flask) hat eine Fortsetzung von "Advanced Flask Patterns" veröffentlicht, die einen Beispielcode zeigt, wie man den neuen "flask.g" verwendet. https://speakerdeck.com/mitsuhoniko/advanced-flask-patterns-1 –
auch ein neuer Anfrage Kontext impliziert einen neuen App-Kontext, so sollte es einfach normal funktionieren – Ronny