在尝试实现类级别的缓存装饰器时,我偶然发现了ring
库,该库能够全局存储函数的输入和输出。给定class
的{{1}}定义,基本上可以实现以下行为:
Calculate
这是我尝试通过import ring
class Calculate:
@ring.dict({})
def sum(self, a, b):
print('actually calculating')
sum = a + b
return sum
Calculate
现在,我需要使用>>> calculate = Calculate()
>>> calcualte.sum(5,7)
actually calculating
12
>>> different_calculate = Calculate()
>>> different_calculate.sum(5,7)
12 #this outputs 12 straight from the cache from first calculate.
#Note that even if 'different_calculate' and 'calculate' are different instantiations of 'Calculate', the cache works at a class level. Therefore the sum is not actually REcalculated.
实现相同的行为,这次是一个属性。我在这里面临的问题是,在sum
@property
中将def
作为参数。因此,当尝试像上一个示例中那样进行缓存时,它将不起作用,因为输入不再是self
和num1
而是num2
,它随每个实例化而改变。因此,它永远不会在不同的类实例上从缓存中拉出,因为self总是随每个实例而变化。见下文:
self
要解决此问题,我必须以某种方式告诉缓存库不要将import ring
class Calculate:
def __init__(self, num1, num2):
self.num1 = num1
self.num2 = num2
@ring.dict({})
@property
def sum(self):
print('actually calculating')
sum = num1 + num2
return sum
>>> calculate = Calculate()
>>> calcualte.sum(5,7)
actually calculating
12
>>> different_calculate = Calculate()
>>> different_calculate.sum(5,7)
actually calculating
12
作为输入,而是将self
,self.num1
视为输入。然后代码将变成这样:
self.num2
我可以用 @ring.dict(self.num1, self.num2) # <--- this does not exist
@property
def sum(self):
print('actually calculating')
sum = num1 + num2
return sum
或其他任何python缓存库来实现此目的吗?
答案 0 :(得分:0)
因此,从here得到一些启发之后,我最终只是创建了自己的记忆功能,如下所示:
memo = {}
def memoize(*attrs):
def wrapper(f):
def helper(obj):
key = tuple([getattr(obj,attr) for attr in attrs])
if key not in memo:
memo[key] = f(obj)
return memo[key]
return helper
return wrapper
class Calculate:
def __init__(self, num1, num2):
self.num1 = num1
self.num2 = num2
@property
@memoize('num1', 'num2')
def sum(self):
print('actually calculating')
sum = self.num1 + self.num2
return sum
>>> calculate = Calculate(6,9)
>>> calculate.sum
actually calculating
15
>>> another_calculate = Calculate(6,9)
>>> another_calculate.sum
15