Ако проверим документите за глобално приложение на flask, flask.g
, пише:
За споделяне на данни, които са валидни само за една заявка от една функция към друга, глобалната променлива не е достатъчно добра, защото би се счупила в среда с нишки. Flask ви предоставя специален обект което гарантира, че е валидно само за активната заявка и това ще върне различни стойности за всяка заявка.
Това се постига чрез използване на локален прокси сървър (в flask/globals.py
):
g = LocalProxy(partial(_lookup_app_object, 'g'))
Другото нещо, което трябва да имаме предвид е, че Python изпълнява първия проход на нашия декоратор по време на фазата на "компилиране", извън всяка заявка или flask
приложение. Това означава key
на аргумента се присвоява стойност на 'shop_{}_style'.format(g.city.id)
когато приложението ви стартира (когато вашият клас се анализира/декорира), извън flask
контекст на заявката.
Но можем лесно да забавим достъпа до flask.g
чрез използване на мързелив прокси, който извлича стойността само когато се използва, чрез функция за обратно извикване. Нека използваме този, който вече е в комплект с 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
Като цяло (за не-flask
или не-werkzeug
apps), можем да използваме подобен LazyProxy
от ProxyTypes
пакет.
Без връзка с това, вие също ще искате да коригирате своя redis_hash_shop_style
декоратор не само да извлича от redis
, но също така да актуализирате (или създадете) стойността, ако е остаряла (или не съществува), като извикате обвитата f()
когато е подходящо.