当前位置:  开发笔记 > 编程语言 > 正文

在python中模拟'local static'变量

如何解决《在python中模拟'localstatic'变量》经验,为你挑选了3个好方法。

请考虑以下代码:

def CalcSomething(a):
    if CalcSomething._cache.has_key(a):
      return CalcSomething._cache[a]
    CalcSomething._cache[a] = ReallyCalc(a)
    return CalcSomething._cache[a] 

CalcSomething._cache = { }

这是我在python中模拟"局部静态"变量时最容易想到的方法.
让我困扰的是,CalcSomething._cache是函数的定义之外被提及,但另一种方法是类似的东西:

if not hasattr(CalcSomething, "_cache"):  
    setattr(CalcSomething, "_cache", { } )  

在函数的定义中,这真的很麻烦.

有更优雅的方式吗?

[编辑]
只是为了澄清,这个问题不是关于本地函数缓存,正如上面的例子所暗示的那样.这是另一个简短的例子,其中'静态本地'可能很方便:

def ParseString(s):
    return ParseString._parser.parse(s)  
# Create a Parser object once, which will be used for all parsings.
# Assuming a Parser object is heave on resources, for the sake of this example.
ParseString._parser = Parser() 

S.Lott.. 52

把它变成一个可调用的对象(因为它实际上就是这样.)

class CalcSomething(object):
    def __init__(self):
        self._cache = {}
    def __call__(self, a):
        if a not in self._cache: 
            self._cache[a] = self.reallyCalc(a)
        return self._cache[a]
    def reallyCalc(self, a):
        return # a real answer
calcSomething = CalcSomething()

现在你可以calcSomething像使用它一样使用它.但它仍然是整洁和自足的.



1> S.Lott..:

把它变成一个可调用的对象(因为它实际上就是这样.)

class CalcSomething(object):
    def __init__(self):
        self._cache = {}
    def __call__(self, a):
        if a not in self._cache: 
            self._cache[a] = self.reallyCalc(a)
        return self._cache[a]
    def reallyCalc(self, a):
        return # a real answer
calcSomething = CalcSomething()

现在你可以calcSomething像使用它一样使用它.但它仍然是整洁和自足的.



2> Torsten Mare..:

把它变成装饰者.

def static_var(var_name, initial_value):
    def _set_var(obj):
        setattr(obj, var_name, initial_value)
        return obj
    return _set_var

@static_var("_cache", {})
def CalcSomething(a):
    ...



3> Abgan..:

考虑编写将保持缓存的装饰器,您的功能不会被缓存代码污染:

def cacheResults(aFunc):
    '''This decorator funcion binds a map between the tuple of arguments 
       and results computed by aFunc for those arguments'''
    def cachedFunc(*args):
        if not hasattr(aFunc, '_cache'):
            aFunc._cache = {}
        if args in aFunc._cache:
            return aFunc._cache[args]
        newVal = aFunc(*args)
        aFunc._cache[args] = newVal
        return newVal
    return cachedFunc

@cacheResults
def ReallyCalc(a):
    '''This function does only actual computation'''
    return pow(a, 42)

也许它一开始看起来不太好,但你可以cacheResults()在任何你不需要关键字参数的地方使用.可以创建类似的装饰器,也适用于关键字参数,但这次似乎没有必要.

推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有