我正在尝试为将记住结果的类的实例方法构建一个装饰器。(这已经做过一百万次了)但是,我希望能够在任何时候重置记忆缓存的选项(例如,如果实例状态中的某些内容发生了变化,这可能会改变方法的结果没有任何内容与它的参数有关)。因此,我尝试将装饰器构建为类而不是函数,以便我可以作为类成员访问缓存。这使我走上了学习描述符的道路,特别是__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:
return self
# new_func is the bound method my_func of my_class instance
new_func = self.func.__get__(obj, objtype)
# instantiates a brand new class...this is not helping us, because it's a
# new class each time, which starts with a fresh cache
return self.__class__(new_func)
# new method that will allow me to reset the memoized cache
def reset(self):
print "IN RESET"
self.cache = {}
class my_class:
@memoized
def my_func(self, val):
print "in my_func"
time.sleep(2)
return val
c = my_class()
print "should take time"
print c.my_func(55)
print
print "should be instant"
print c.my_func(55)
print
c.my_func.reset()
print "should take time"
print c.my_func(55)
这清楚和/或可能吗?每次__get__
调用时,我都会得到一个全新的记忆类实例,它会丢失包含实际数据的缓存。我一直在努力工作__get__
,但没有取得太大进展。
是否有一个完全独立的方法来解决我完全遗漏的这个问题?欢迎和赞赏所有建议/建议。谢谢。