记住使用实例属性的函数

时间:2013-06-18 10:49:19

标签: python caching memoization python-decorators

我是python的新手,我无法在线找到答案。 假设我有一个方法可以进行一些计算并返回一个字符串

def output(self)
     a=self.some_long computation1()
     b=self.some_long computation2()
     c=self.some_attribute
     some_computatuion_inside
     return output_string

我在一些地方使用这个功能并且想要记住它,但由于它不需要参数并且依赖于可以在调用之间改变的实例属性,我不知道如何继续,

我意识到我可以编写自己的memoization函数,它将检查这些属性是否发生了变化,但这似乎是不正确的,因为这只是特定于此函数 我希望将来可以为其他功能做同样的事情

2 个答案:

答案 0 :(得分:1)

一种方法是提取变量(假设它们是可清除的)并使其为static method

@staticmethod
def output_static(a, b, c)
     some_computatuion_inside
     return output_string

然后从课堂内调用它:

self.output_static(a=self.some_long_computation1()
                   b=self.some_long_computation2()
                   c=self.some_attribute)

您还可以使用技术来记忆some_long_computation1some_long_computation1

如果你想要,你可以编写一个中间辅助函数,它只需调用(memomized)静态方法:

def output(self):
    return self.output_static(a=self.some_long_computation1()
                              b=self.some_long_computation2()
                              c=self.some_attribute)

答案 1 :(得分:1)

装饰者可以根据任何参数计算密钥。任何实例方法都有一个参数,即self,并且很容易使用它来获取方法的memoize装饰器:

CACHE = {}

def memoize(*attributes):
    def decorator(meth):
        def wrapper(self):
            key = tuple(getattr(self, attr) for attr in attributes)
            try:
                result = CACHE[key]
            except KeyError:
                result = CACHE[key] = meth(self)
            return result
        return wrapper
    return decorator

用法:

class Factorial(object):
    def __init__(self, n):
        self.n = n
    @memoize('n')
    def compute(self):
        if self.n in (0,1): return self.n
        else:
            return Factorial(self.n-1).compute() + Factorial(self.n-2).compute()


f = Factorial(100)

f.compute()
Out[4]: 354224848179261915075L