Om vi kontrollerar dokumenten för flask application global, flask.g
, står det:
För att dela data som är giltig för en begäran endast från en funktion till en annan, är en global variabel inte tillräckligt bra eftersom den skulle gå sönder i trådade miljöer. Flask ger dig ett speciellt objekt som säkerställer att den endast är giltig för den aktiva begäran och det kommer att returnera olika värden för varje begäran.
Detta uppnås genom att använda en trådlokal proxy (i flask/globals.py
):
g = LocalProxy(partial(_lookup_app_object, 'g'))
Det andra vi bör tänka på är att Python kör det första passet av vår dekoratör under "kompileringsfasen", utanför varje begäran eller flask
Ansökan. Det betyder key
argument tilldelas värdet 'shop_{}_style'.format(g.city.id)
när din ansökan startar (när din klass analyseras/dekoreras), utanför flask
begär sammanhang.
Men vi kan enkelt fördröja åtkomsten till flask.g
genom att använda en lazy proxy, som hämtar värdet endast när den används, via callback-funktionen. Låt oss använda den som redan är buntad 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
I allmänhet (för icke-flask
eller icke-werkzeug
appar) kan vi använda en liknande LazyProxy
från ProxyTypes
paket.
Utan koppling till detta vill du också fixa din redis_hash_shop_style
dekorator för att inte bara hämta från redis
, men för att också uppdatera (eller skapa) värdet om det är inaktuellt (eller icke-existerande), genom att anropa den inslagna f()
när det är lämpligt.