sql >> Base de Datos >  >> NoSQL >> Redis

python matraz cómo pasar un parámetro dinámico a un decorador

Si revisamos los documentos para la aplicación de matraz global, flask.g , dice:

Para compartir datos que son válidos solo para una solicitud de una función a otra, una variable global no es lo suficientemente buena porque se rompería en entornos con subprocesos. Flask te proporciona un objeto especial eso asegura que es solo válido para la solicitud activa y eso devolverá diferentes valores para cada solicitud.

Esto se logra mediante el uso de un proxy local de subprocesos (en flask/globals.py ):

g = LocalProxy(partial(_lookup_app_object, 'g'))

La otra cosa que debemos tener en cuenta es que Python está ejecutando el primer paso de nuestro decorador durante la fase de "compilación", fuera de cualquier solicitud o flask solicitud. Eso significa key al argumento se le asigna un valor de 'shop_{}_style'.format(g.city.id) cuando se inicia su aplicación (cuando su clase está siendo analizada/decorada), fuera de flask solicitar contexto.

Pero podemos retrasar fácilmente el acceso a flask.g mediante el uso de un proxy perezoso, que obtiene el valor solo cuando se usa, a través de la función de devolución de llamada. Usemos el que ya viene con flask , el 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

En general (para no flask o no werkzeug aplicaciones), podemos usar un LazyProxy similar de los ProxyTypes paquete.

Sin relación con esto, también querrá arreglar su redis_hash_shop_style decorador para no solo obtener de redis , pero también para actualizar (o crear) el valor si está obsoleto (o no existe), llamando al f() envuelto cuando corresponda.