【问题标题】:Memoize a function which uses instance attributes记忆一个使用实例属性的函数
【发布时间】:2013-06-14 13:22:18
【问题描述】:

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

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

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

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

【问题讨论】:

  • 尝试考虑some_long_computationX memoization

标签: python caching memoization python-decorators


【解决方案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

如果你愿意,你可以编写一个中间辅助函数,它会简单地调用(记忆的)静态方法:

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

【讨论】:

    【解决方案2】:

    装饰器可以根据任何参数计算密钥。任何实例方法都有一个参数,即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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-02
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 2021-12-23
      • 1970-01-01
      • 2019-01-20
      • 2021-10-23
      相关资源
      最近更新 更多