本质上,我想在堆栈上放置一个变量,堆栈上该部分下方的所有调用都可以访问该变量,直到块退出。在Java中,我会使用支持方法的本地静态线程来解决这个问题,然后可以从方法中访问它。
典型例子:你得到一个请求,并打开一个数据库连接。在请求完成之前,您希望所有代码都使用此数据库连接。完成并关闭请求后,关闭数据库连接。
我需要这个,是一个报告生成器。每个报告由多个部分组成,每个部分可以依赖于不同的计算,有时不同的部分部分依赖于相同的计算。因为我不想重复繁重的计算,所以我需要缓存它们。我的想法是用缓存装饰器来装饰方法。缓存根据方法名称和模块创建一个 id,它是参数,查看它是否已经在堆栈变量中计算了这个,如果没有,则执行该方法。
我将通过展示我当前的实现来尝试和清除。我想做的是简化那些实现计算的代码。
首先,我有中央缓存访问对象,我称之为 MathContext:
class MathContext(object):
def __init__(self, fn):
self.fn = fn
self.cache = dict()
def get(self, calc_config):
id = create_id(calc_config)
if id not in self.cache:
self.cache[id] = calc_config.exec(self)
return self.cache[id]
fn 参数是创建上下文相关的文件名,可以从中读取数据以进行计算。
然后我们有 Calculation 类:
class CalcBase(object):
def exec(self, math_context):
raise NotImplementedError
这是一个愚蠢的斐波那契示例。这些方法实际上都不是递归的,它们适用于大量数据,但它可以证明您将如何依赖其他计算:
class Fibonacci(CalcBase):
def __init__(self, n): self.n = n
def exec(self, math_context):
if self.n < 2: return 1
a = math_context.get(Fibonacci(self.n-1))
b = math_context.get(Fibonacci(self.n-2))
return a+b
相反,我希望斐波那契只是一种装饰方法:
@cache
def fib(n):
if n<2: return 1
return fib(n-1)+fib(n-2)
在 math_context 示例中,当 math_context 超出范围时,它的所有缓存值也会如此。我想要装饰师也一样。IE。在 X 点,@cache 缓存的所有内容都被取消引用为 gced。