我正在尝试为类的实例方法构建一个装饰器来记忆结果.(之前已经完成了一百万次)但是,我希望能够在任何时候重置memoized缓存(例如,如果实例状态中的某些内容发生更改,这可能会更改无方法的结果)与它的args相关).所以,我试图建立一个装饰为一类,而不是一个函数,这样我可以有机会获得高速缓存作为一个类的成员.这导致我学习描述符的路径,特别是__get__方法,这是我实际上被困的地方.我的代码看起来像这样:
import time
class memoized(object):
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args, **kwargs):
key = (self.func, args, frozenset(kwargs.iteritems()))
try:
return self.cache[key]
except KeyError:
self.cache[key] = self.func(*args, **kwargs)
return self.cache[key]
except TypeError:
# uncacheable, so just return calculated value without caching
return self.func(*args, **kwargs)
# self == instance of memoized
# obj == instance of my_class
# objtype == class object of __main__.my_class
def __get__(self, obj, objtype=None):
"""Support instance methods"""
if obj is None: …Run Code Online (Sandbox Code Playgroud) 从这里使用Memoized装饰器的接受答案(带有doctests): 可以做些什么来加速这个memoization装饰器?
和以下代码(fib.py):
class O(object):
def nfib(self,n): # non-memoized fib fn
if n in (0, 1):
return n
return self.nfib(n-1) + self.nfib(n-2)
@Memoized
def fib(self,n): # memoized fib fn
if n in (0, 1):
return n
return self.fib(n-1) + self.fib(n-2)
if __name__ == '__main__':
import time
o = O()
stime = time.time()
print "starting non-memoized"
for i in range(10):
print o.nfib(32)
print "finished non-memoized - elapsed secs =", time.time() - stime
stime = time.time()
print "starting memoized"
for …Run Code Online (Sandbox Code Playgroud)