2016-03-05 79 views
0

我需要做一個裝飾器,檢查它的相關函數之前是否調用與它現在調用的參數完全相同的參數。如果是,我需要返回以前的輸出。如果沒有,我打電話並存儲結果以備將來調用。這裏是我的:Python裝飾器,檢查函數是否被調用之前

class memoized(object): 
    def __init__(self,f): 
     self.__first=[] 
     self.__last=[] 
     self.__f=f 
     self.__name__=f.__name__ 
     self.__value=[] 
    def __call__(self,*args,**dargs): 
     for i in self.__value: 
      if(self.__first[i]==args and self.__last[i]==dargs): 
       return self.__value[i] 
     rv=self.__f(*args,**dargs) 
     self.__first.append(args) 
     self.__last.append(dargs) 
     self.__value.append(rv) 
     return rv 

當我運行它雖然它給了我一個idex錯誤。我不知道爲什麼從理論上講,首先和最後一個值的長度應該一直是相同的,因爲我追加了所有其中的3個。有任何想法嗎?

+0

請將追溯到您的問題。 – zondo

+0

這通常被稱爲* memoization *,看到一個[相關的問題](http://stackoverflow.com/q/1988804) –

回答

1

您附加返回值self.__value。迭代self.__value然後給你那些返回值,沒有索引到列表

你可以使用zip()這裏配對的3分列出來代替:

for a, kw, rv in zip(self.__value, self.__first, self.__last): 
    if(a==args and kw==dargs): 
     return rv 

您可以將位置和關鍵字參數以及追加到相同的列表,只要您的實現而言。有一個在這裏創建3所單獨列出小點:

class memoized(object): 
    def __init__(self,f): 
     self.__cache = [] 
     self.__f = f 
     self.__name__ = f.__name__ 
    def __call__(self,*args,**dargs): 
     for a, kw, rv in self.__cache: 
      if(a == args and kw == dargs): 
       return rv 
     rv = self.__f(*args, **dargs) 
     self.__cache.append((args, dargs, rv)) 
     return rv 

您可能希望找到一個方法來創建一個從位置和關鍵字參數的哈希的關鍵代替,這樣你就可以使用字典從地圖( )表示緩存值的參數。這避免了必須循環遍歷全部緩存條目。

+0

哦哇,這是一個愚蠢的錯誤。謝謝 –

+0

是的,我想我可以做一個列表 –

相關問題