Python – кэширование свойства, чтобы избежать будущих вычислений

В следующем примере cached_attr используется для получения или установки атрибута в экземпляре модели, когда related_spam дорогостоящий для базы данных ( related_spam в примере). В этом примере я использую cached_spam для сохранения запросов. Я устанавливаю инструкции печати при настройке и при получении значений, чтобы я мог проверить это. Я проверил его в представлении, передав экземпляр Egg в представление и в представлении с помощью {{ egg.cached_spam }} , а также другие методы модели Egg которые совершают вызовы cached_spam . Когда я закончил и протестировал его, вывод оболочки на сервере разработки Django показал, что кеш атрибутов был пропущен несколько раз, а также успешно получил несколько раз. Кажется, это непоследовательно. С теми же данными, когда я сделал небольшие изменения (как только изменил строку строки печати) и обновил (со всеми одинаковыми данными), произошло различное количество промахов / успехов. Как и почему это происходит? Является ли этот код неправильным или очень проблематичным?

 class Egg(models.Model): ... fields @property def related_spam(self): # Each time this property is called the database is queried (expected). return Spam.objects.filter(egg=self).all() # Spam has foreign key to Egg. @property def cached_spam(self): # This should call self.related_spam the first time, and then return # cached results every time after that. return self.cached_attr('related_spam') def cached_attr(self, attr): """This method (normally attached via an abstract base class, but put directly on the model for this example) attempts to return a cached version of a requested attribute, and calls the actual attribute when the cached version isn't available.""" try: value = getattr(self, '_p_cache_{0}'.format(attr)) print('GETTING - {0}'.format(value)) except AttributeError: value = getattr(self, attr) print('SETTING - {0}'.format(value)) setattr(self, '_p_cache_{0}'.format(attr), value) return value 

2 Solutions collect form web for “Python – кэширование свойства, чтобы избежать будущих вычислений”

Насколько это плохо. Проблема, вероятно, не существует, но в том, как вы используете этот код.

Главное, чтобы понять, что экземпляры модели не имеют идентичности. Это означает, что если вы где-то создаете экземпляр объекта Egg и другого в другом месте, даже если они ссылаются на одну и ту же базовую строку базы данных, они не будут разделять внутреннее состояние. Поэтому вызов cached_attr на одном не приведет к тому, что кеш будет заполнен в другом.

Например, если у вас есть класс RelatedObject с ForeignKey to Egg:

 my_first_egg = Egg.objects.get(pk=1) my_related_object = RelatedObject.objects.get(egg__pk=1) my_second_egg = my_related_object.egg 

Здесь my_first_egg и my_second_egg относятся к строке базы данных с pk 1, но они не являются одним и тем же объектом:

 >>> my_first_egg.pk == my_second_egg.pk True >>> my_first_egg is my_second_egg False 

Итак, заполнение кеша my_first_egg не заполняет его my_second_egg .

И, конечно, объекты не будут сохраняться в запросах (если они специально не сделаны глобальными, что ужасно), поэтому кеш не будет сохраняться.

Серверы Http, которые масштабируются, не имеют общего доступа; вы не можете полагаться на что-то одиночное. Для совместного использования состояния вам необходимо подключиться к службе специального назначения.

Поддержка кэширования Django подходит для вашего использования. Это не обязательно глобальный синглтон; если вы используете locmem:// , это будет процессно-локальный, что может быть более эффективным выбором.

  • Django аннотированные группы по месяцам
  • «Следующий» параметр, перенаправление, django.contrib.auth.login
  • Поиск всех классов, полученных из заданного базового класса в python
  • Форматирование чисел в шаблонах django
  • Схема Django Test с файловым сервером электронной почты
  • Django WSGI Apache VirtualHost, возвращающий ошибку 404
  • Асинхронная обработка Django
  • не может добавить встроенную в django админную инфраструктуру сайта
  • Python - лучший язык программирования в мире.