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

В следующем примере cached_attr используется для получения или установки атрибута в экземпляре модели, когда ресурсоемкое свойство базы данных ( 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
5
задан orokusaki 26 November 2010 в 22:55
поделиться