Hvis vi tjekker dokumenterne for flask application global, flask.g
, står der:
For at dele data, der kun er gyldige for én anmodning, fra én funktion til en anden, er en global variabel ikke god nok, fordi den ville bryde i trådede miljøer. Flask giver dig en særlig genstand der sikrer, at den kun er gyldig for den aktive anmodning og det vil returnere forskellige værdier for hver anmodning.
Dette opnås ved at bruge en tråd-lokal proxy (i flask/globals.py
):
g = LocalProxy(partial(_lookup_app_object, 'g'))
Den anden ting, vi bør huske på, er, at Python udfører det første gennemløb af vores dekoratør under "kompileringsfasen" uden for enhver anmodning eller flask
Ansøgning. Det betyder key
argument får tildelt værdien 'shop_{}_style'.format(g.city.id)
når din ansøgning starter (når din klasse bliver parset/dekoreret), uden for flask
anmodningskontekst.
Men vi kan nemt forsinke adgangen til flask.g
ved at bruge en doven proxy, som kun henter værdien ved brug, via tilbagekaldsfunktion. Lad os bruge den, der allerede er bundtet med flask
, 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
Generelt (for ikke-flask
eller ikke-werkzeug
apps), kan vi bruge en lignende LazyProxy
fra ProxyTypes
pakke.
Uden at være relateret til dette, vil du også gerne rette din redis_hash_shop_style
dekorator til ikke kun at hente fra redis
, men også at opdatere (eller oprette) værdien, hvis den er forældet (eller ikke-eksisterende), ved at kalde den indpakkede f()
når det er relevant.