2016-08-29 126 views
0

的操作我有下面的代碼:Python的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) 

(注意缺乏paren論文)。

functools.lru_cache(maxsize=None)不同,它會保留一個無限大小的字典(在殺死程序之前它會增加大小),reify裝飾器將計算結果緩存到實例本身。如果實例是垃圾收集的,那麼它的緩存加權回報也是如此。