Als we de documenten voor flask application global controleren, flask.g
, er staat:
Om gegevens te delen die alleen geldig zijn voor één aanvraag van de ene functie naar de andere, is een globale variabele niet goed genoeg omdat deze zou breken in threaded-omgevingen. Flask biedt je een speciaal object die ervoor zorgt dat het alleen geldig is voor het actieve verzoek en dat levert verschillende waarden op voor elk verzoek.
Dit wordt bereikt door een thread-local proxy te gebruiken (in flask/globals.py
):
g = LocalProxy(partial(_lookup_app_object, 'g'))
Het andere dat we in gedachten moeten houden, is dat Python de eerste passage van onze decorateur uitvoert tijdens de "compileer" -fase, buiten elk verzoek, of flask
sollicitatie. Dat betekent key
argument krijgt een waarde van 'shop_{}_style'.format(g.city.id)
toegewezen wanneer je aanvraag start (wanneer je klas wordt geparseerd/ingericht), buiten flask
context opvragen.
Maar we kunnen de toegang tot flask.g
gemakkelijk uitstellen door een luie proxy te gebruiken, die de waarde alleen ophaalt wanneer deze wordt gebruikt, via de callback-functie. Laten we degene gebruiken die al gebundeld is met flask
, de werkzeug.local.LocalProxy
:
from werkzeug.local import LocalProxy
class ShopAreaAndStyleListAPI(Resource):
@redis_hash_shop_style(key=LocalProxy(lambda: 'shop_{}_style'.format(g.city.id)))
def get(self):
# if not found from redis, query from mysql
pass
In het algemeen (voor niet-flask
of niet-werkzeug
apps), kunnen we een vergelijkbare LazyProxy
. gebruiken van de ProxyTypes
pakket.
Los hiervan, wil je ook je redis_hash_shop_style
repareren decorateur om niet alleen op te halen uit redis
, maar om ook de waarde bij te werken (of te maken) als deze verouderd (of niet-bestaand) is, door de ingepakte f()
aan te roepen indien van toepassing.