Jeśli sprawdzimy dokumentację dla aplikacji flask global, flask.g
, jest napisane:
Aby udostępnić dane, które są ważne dla jednego żądania, tylko z jednej funkcji do drugiej, zmienna globalna nie jest wystarczająco dobra, ponieważ mogłaby się zepsuć w środowiskach wątkowych. Flask zapewnia specjalny obiekt to zapewnia, że jest ważne tylko dla aktywnego żądania a to zwróci różne wartości dla każdego żądania.
Osiąga się to za pomocą lokalnego serwera proxy wątków (w flask/globals.py
):
g = LocalProxy(partial(_lookup_app_object, 'g'))
Inną rzeczą, o której powinniśmy pamiętać, jest to, że Python wykonuje pierwszy przebieg naszego dekoratora podczas fazy "kompilacji", poza jakimkolwiek żądaniem lub flask
podanie. Oznacza to key
argument otrzyma przypisaną wartość 'shop_{}_style'.format(g.city.id)
kiedy twoja aplikacja jest uruchamiana (kiedy twoja klasa jest analizowana/dekorowana), poza flask
kontekst żądania.
Ale możemy łatwo opóźnić dostęp do flask.g
za pomocą leniwego proxy, które pobiera wartość tylko wtedy, gdy jest używane, za pomocą funkcji zwrotnej. Użyjmy tego, który jest już dołączony do 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
Ogólnie (dla nie flask
lub inne niż werkzeug
aplikacje), możemy użyć podobnego LazyProxy
z ProxyTypes
pakiet.
Niezwiązane z tym, będziesz także chciał naprawić swój redis_hash_shop_style
dekorator do pobierania nie tylko z redis
, ale także zaktualizować (lub utworzyć) wartość, jeśli jest nieaktualna (lub nieistniejąca), wywołując opakowaną f()
w razie potrzeby.