我正在编写一个类,它有一些计算量大的方法和一些用户想要迭代调整的参数,并且与计算无关。
实际用途是用于可视化,但这是一个卡通示例:
class MyClass(object):
def __init__(self, x, name, mem=None):
self.x = x
self.name = name
if mem is not None:
self.square = mem.cache(self.square)
def square(self, x):
"""This is the 'computation heavy' method."""
return x ** 2
def report(self):
"""Use the results of the computation and a tweakable parameter."""
print "Here you go, %s" % self.name
return self.square(self.x)
基本思想是用户可能希望使用相同的x
但不同的name
参数创建此类的许多实例。我想允许用户提供一个joblib.Memory
对象来缓存计算部分,这样他们就可以“报告”许多不同的名称,而不必每次都重新计算平方数组。
(这有点奇怪,我知道。用户需要为每个名称设置不同的类实例的原因是他们实际上正在与看起来像这样的接口函数进行交互。
def myfunc(x, name, mem=None):
theclass = MyClass(x, name, mem)
theclass.report()
但是现在让我们忽略它。
关注joblib docs我正使用行square
缓存self.square = mem.cache(self.square)
函数。问题在于,因为self
对于不同的实例会有所不同,所以即使参数相同,每次都会重新计算数组。
我猜测处理此问题的正确方法是将行更改为
self.square = mem.cache(self.square, ignore=["self"])
但是,这种方法有什么缺点吗?有没有更好的方法来完成缓存?
答案 0 :(得分:0)
来自docs,
如果要在类中使用缓存,推荐的模式是缓存纯函数并使用类中的缓存函数。
由于您希望内存缓存是可选的,我建议使用以下内容:
def square_function(x):
"""This is the 'computation heavy' method."""
print ' square_function is executing, not using cached result.'
return x ** 2
class MyClass(object):
def __init__(self, x, name, mem=None):
self.x = x
self.name = name
if mem is not None:
self._square_function = mem.cache(square_function)
else:
self._square_function = square_function
def square(self, x):
return self._square_function(x)
def report(self):
print "Here you go, %s" % self.name
return self.square(self.x)
from tempfile import mkdtemp
cachedir = mkdtemp()
from joblib import Memory
memory = Memory(cachedir=cachedir, verbose=0)
objects = [
MyClass(42, 'Alice (cache)', memory),
MyClass(42, 'Bob (cache)', memory),
MyClass(42, 'Charlie (no cache)')
]
for obj in objects:
print obj.report()
执行收益率:
Here you go, Alice (cache)
square_function is executing, not using cached result.
1764
Here you go, Bob (cache)
1764
Here you go, Charlie (no cache)
square_function is executing, not using cached result.
1764