2016-03-05 70 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

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