Загрузка маринованного списка только один раз - Django \ Python - PullRequest
2 голосов
/ 08 февраля 2011

У меня есть файл pickle, который содержит список скомпилированных регулярных выражений и другие данные.

Загрузка занимает около 1-1,5 секунды.

Что может быть хорошим способом использования этого списка в моих представлениях, но только один раз работать с файлом pickle?

Edit:

будет ли импорт в settings.py рассматриваться нормально?


Есть идеи?

Ответы [ 3 ]

2 голосов
/ 08 февраля 2011

Я бы написал модуль Python - одноэлементный класс с методом init, который считывает выбранные данные в объект Python, а затем любые методы get, которые вам нужны, чтобы получить информацию.

Затемв вашем settings.py вы просто вызываете метод инициализации.Все, что нужно для получения информации, просто импортирует модуль и использует методы get.

2 голосов
/ 08 февраля 2011

Как вы можете это сделать

Создайте модуль с именем cache.py, затем:

import cache
data = getattr(cache, 'data', '') or get_my_data()

Это перезагрузит данные только один раз процессом сервера (что будет зависеть от ваших настроек, ваш веб-сервер и везде, где вы используете WSGI или CGI).На веб-сервере разработчика (./manage.py runserver) каждый раз, когда вы изменяете файл, кеш будет аннулироваться.

Как это работает

Модули в Python импортируются только один раз для каждого Pythonпроцесс.Если вы используете import несколько раз, он вернет только ссылку на уже импортированный модуль.Таким образом, если у вас Apache, на котором запущено mod_wsgi с 4 работниками, get_my_data() будет вызываться только 4 раза, поскольку работают только 4 процесса Python.Помните, что работник может умереть, быть перезагружен, убит и т. Д. Но он должен сводить к минимуму вызовы get_my_data().

Понятно: если один процесс изменяет данные кэша, другие не будутзнать об этом. Если ваши данные должны быть статичными, это нормально.Если вам нужно поддерживать его в актуальном состоянии, он не будет работать.Это верно для этого метода или любого метода, подразумевающего использование одиночного, если только вы не можете гарантировать, что у вас запущен только один процесс Python (что вы можете, но это не цель этого ответа).

О синтаксисе:

getattr(cache, 'data', '') вернуть атрибут с именем «data» объекта «cache».Если он не существует, он возвращает последние параметры, здесь пустую строку.

В Python or ленив и прекратит оценку параметров, если он может вернуться.В нашем случае, если «data» является атрибутом кеша, он будет True в логическом контексте, or будет считать, что он уже выполнил свою работу (поскольку для возврата ему нужно только одно значение TrueTrue) и вернет True без запуска get_my_data().Однако, если 'data' не является атрибутом кэша, тогда, если or будет оценивать пустую строку, рассмотрите ее как False, затем запустите get_my_data().

Почему вы, вероятно, нев любом случае не хочу этого делать

  1. Если вы загружаете для каждой страницы своего веб-сайта что-то, что генерирует 2 секунды для каждого запроса, что-то не так.Возможно, вы захотите переосмыслить свою архитектуру.
  2. Если данные не предназначены для возврата значения, а скорее запускают процесс после действия пользователя, то, вероятно, лучше запустить асинхронную функцию, используя такие инструменты, как Celery .
  3. Модуль re кэширует регулярные выражения в любом случае, поэтому вам, вероятно, больше не нужно их компилировать.Другие данные, вероятно, могут быть выражены как примитивные.Храните их все как строки и другие примитивы в бэкэнде кэша, таком как memcached или redis , это будет намного чище. Плюс, если один Python обрабатывает обновление кеша, то другие будут об этом знать.Они не соответствуют приведенному выше фрагменту.

Последнее слово о settings.py

Не следует указывать в файле settings.py:

  • Если вы жестко закодируете его, ваш файл настроек станет нечитаемым, и его раздражает использование инструмента управления исходным кодом.
  • Вы не можете поместить его здесь динамически, поскольку модуль настроек доступен только для чтения в Django,если вы не используете некрасивые хаки, это может привести к неожиданным проблемам.
1 голос
/ 08 февраля 2011

Вы можете загрузить его, а затем использовать инфраструктуру кэширования django для его хранения, таким образом, он будет загружен только один раз.

http://docs.djangoproject.com/en/dev/topics/cache/

...