2017-02-11 18 views
0

Рассмотрим следующий пример: минимальныйКак memoize свойство в Python?

class Foo(object): 

    def __init__(self): 
     self.b = self.a = 1 

    @property 
    def sum(self): 
     print 'Recalculating sum' 
     return self.a + self.b 

foo = Foo() 
print foo.sum 
print foo.sum # Prints 'Recalculating sum' even though neither a or b has changed since previous call 
foo.a = 2 
print foo.sum # a has been changed to 2 so recalculation is necessary 

Я хотел бы memoize sum такое, что если self.a и self.b не изменится, то мы не должны держать перерасчета собственность.

Свойство должно быть пересчитано только при изменении self.a или self.b - есть ли простой способ сделать это?

ответ

0

Используйте свойства для a и b тоже и очистить кэш в инкубационных:

class Foo(object): 

    def __init__(self): 
     self.a = 1 
     self.b = 1 

    @property 
    def a(self): 
     return self._a 

    @a.setter 
    def a(self, value): 
     self._a = value 
     self._clearsum() 

    @property 
    def b(self): 
     return self._b 

    @b.setter 
    def b(self, value): 
     self._b = value 
     self._clearsum() 

    def _clearsum(self): 
     self._sum = None 

    @property 
    def sum(self): 
     if self._sum is None: 
      self._sum = self.a + self.b 
     return self._sum 

Или, если вы хотите что-то немного больше общего, вы можете проверить это тоже: Storing calculated values in an object

Редактировать : кто-то недавно предложил добавить self._sum = None в __init__, чтобы «избежать ошибки при доступе к сумме», но это на самом деле не нужно - __init__ вызывает a.setter, который вызывает _clearsum, который устанавливает атрибут _sum, поэтому он гарантированно будет self._sum.

 Смежные вопросы

  • Нет связанных вопросов^_^