2016-08-29 2 views
0

У меня есть следующий код:Операция кэша LRU Пайтона

def sharpe(self): 
    return (self.weighted_returns()/self.weighted_returns().std())*np.sqrt(252) 

Где self.weighted_returns() имеет @lru_cache(maxsize=None) декоратора.

Будет ли рассчитываться self.weighted_returns() один или два раза?

+0

Я не уверен, что вы здесь просите. Вы знаете, что делает 'lru_cache'? Если да, то что вас смущает? –

+0

Почему вы используете lru_cache для этого и почему не кэшируете вычисление в самом экземпляре? –

+0

Я не понимаю, почему его нужно называть дважды. Он находится в одной строке, но вызовы оцениваются в строгом порядке. – janbrohl

ответ

0

Для этого можно использовать functools.lru_cache. Но если вы только кешируете вычисления для self, и функция не использует аргумент, это перебор.

Скорее, я бы украсть ленивый reify декоратора из пирамиды:

class reify(object): 
    def __init__(self, wrapped): 
     self.wrapped = wrapped 
     update_wrapper(self, wrapped) 

    def __get__(self, inst, objtype=None): 
     if inst is None: 
      return self 
     val = self.wrapped(inst) 
     setattr(inst, self.wrapped.__name__, val) 
     return val 

И использовать его на weighted_returns, превращая его в лениво вычисленный атрибут:

@reify 
def weighted_returns(self): 
    # calculate the returns using self normally 
    return returns 

Тогда ваш расчет будет

self.weighted_returns/self.weighted_returns.std() * np.sqrt(252) 

(обратите внимание на отсутствие парен диссертаций).

В отличие от functools.lru_cache(maxsize=None), который будет хранить словарь неограниченного размера (он будет увеличиваться в размере до тех пор, пока вы не убьете программу), декоратор reify кэширует результат вычисления на самом экземпляре. Если экземпляр собран на сборку мусора, то и его кэшированные взвешенные возвращения.

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