Сохранение глобального состояния в фляге

Я пытаюсь сохранить словарь кеша в моем приложении flask .

Насколько я понимаю, контекст приложения , в частности, для этого должен использоваться объект flask.g .

Настроить:

 import flask as f app = f.Flask(__name__) 

Теперь, если я это сделаю

 with app.app_context(): fgfoo = "bar" print fgfoo 

он печатает bar .

Продолжая следующее

 with app.app_context(): print fgfoo AttributeError: '_AppCtxGlobals' object has no attribute 'foo' 

Я не понимаю этого, и документы не помогают вообще. Если бы я их правильно прочитал, государство должно было сохраниться.

Еще одна идея, которую я использовал, – просто использовать переменные модуля:

 cache = {} def some_function(): cache['foo'] = "bar" 

но кажется, что они сбрасываются с каждым запросом.

Как это сделать правильно?

Редактировать: Flask 10.1

  • Как использование инструкции try исключает условие гонки?
  • 3 Solutions collect form web for “Сохранение глобального состояния в фляге”

    Основываясь на вашем вопросе, я думаю, вы смущены определением «глобальный».

    В настройке Flask, у вас есть Flask-сервер с несколькими потоками и потенциально несколько процессов, обрабатывающих запросы. Предположим, что у вас была глобальная переменная запаса, такая как «itemlist = []», и вы хотели продолжать добавлять ее в каждый запрос – скажем, каждый раз, когда кто-то делал запрос POST на конечную точку. Это вполне возможно в теории и практике. Это тоже очень плохая идея.

    Проблема в том, что вы не можете легко контролировать, какие потоки и процессы «выигрывают» – список может быть в действительно неуклюжем порядке или полностью поврежден. Итак, теперь вам нужно поговорить о замках, мьютексах и других примитивах. Это сложно и раздражает.

    Вы должны держать вебсервер сам по себе как можно более безгосударственным. Каждый запрос должен быть полностью независимым и не передавать какое-либо состояние на сервере. Вместо этого используйте слой базы данных или кеширования, который будет обрабатывать состояние для вас. Это кажется более сложным, но на практике это проще. Посмотрите, например, SQLite; это довольно просто.

    Чтобы обратиться к объекту 'flask.g', это глобальный объект для каждого запроса .

    http://flask.pocoo.org/docs/api/#flask.g

    Он «очищается» между запросами и не может использоваться для совместного использования состояния между ними.

    Эта строка

     with app.app_context(): fgfoo = "bar" 

    Поскольку вы используете ключевое слово «с», как только этот цикл выполняется, он вызывает __exit__ класса AppContext. Смотрите это . Таким образом, «foo» выталкивается однажды. Вот почему у вас нет его снова. Вместо этого вы можете попробовать:

     ctx = app.app_context() fgfoo = 'bar' ctx.push() 

    Пока вы не назовете следующее, g.foo должен быть доступен

     ctx.pop() 

    Я не уверен, что вы хотите использовать это для кэширования.

    Я сделал что-то похожее на вашу идею об «модульных переменных», которую я использую на сервере флэков, который я использую для интеграции двух компонентов программного обеспечения, где я знаю, что у меня будет только один одновременный «пользователь» (являющийся программным обеспечением отправителя) ,

    Мой app.py выглядит так:

     from flask import Flask from flask.json import jsonify app = Flask(__name__) cache = {} @app.route("/create") def create(): cache['foo'] = 0 return jsonify(cache['foo']) @app.route("/increment") def increment(): cache['foo'] = cache['foo'] + 1 return jsonify(cache['foo']) @app.route("/read") def read(): return jsonify(cache['foo']) if __name__ == '__main__': app.run() 

    Вы можете проверить это следующим образом:

     import requests print(requests.get('http://127.0.0.1:5000/create').json()) print(requests.get('http://127.0.0.1:5000/increment').json()) print(requests.get('http://127.0.0.1:5000/increment').json()) print(requests.get('http://127.0.0.1:5000/read').json()) print(requests.get('http://127.0.0.1:5000/increment').json()) print(requests.get('http://127.0.0.1:5000/create').json()) print(requests.get('http://127.0.0.1:5000/read').json()) 

    Выходы:

     0 1 2 2 3 0 0 

    Следует использовать с осторожностью, поскольку я ожидаю, что это не приведет к правильной многопользовательской веб-серверной среде.

    Python - лучший язык программирования в мире.