2011-06-19 47 views
3

我有一些昂贵的函数f(x),我只想计算一次,但被称为相当频繁。从本质上讲,第一次调用函数时,它应该计算一系列x值的一大堆值,因为它将被整合,然后用样条插值,并以某种方式缓存系数,可能在文件中进一步使用。Python:从函数内重新定义函数

我的想法是做类似下面的事情,因为它很容易实现。第一次调用函数时,它会执行某些操作,然后重新定义自己,然后再执行其他操作。然而,它并不像预期的那样工作,并且通常可能是不好的做法。

def f(): 
    def g(): 
     print(2) 
    print(1) 
    f = g 
f() 
f() 

预期输出:

1 
2 

实际输出:

1 
1 

定义克F()以外()没有帮助。为什么这不起作用?除此之外,我现在能想到的唯一解决方案是使用一些全局变量。或者为此写一个类是否有意义?

回答

6

这太复杂了。相反,使用记忆化:

def memoized(f): 
    res = [] 
    def resf(): 
     if len(res) == 0 
      res.append(f()) 
     return res[0] 
    return resf 

,然后简单地

@memoized 
def f(): 
    # expensive calculation here ... 
    return calculated_value 

在Python 3,你可以用functools.lru_cache取代memoized

+0

+1:[memoization](http://en.wikipedia.org/wiki/Memoization)和[装饰](http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators),允许装饰的Python版本,是要走的路。规范示例[这里](http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize)。 – Johnsyweb

+0

难道你不知道字典是不可能的吗? – juanchopanza

+0

@juanchopanza哎呀,是的。删除了参数,因为无论如何它们在这个示例中都是不必要的。 – phihag

3

更改F IN F公司范围不功能之外的影响,如果你想改变男,你可以使用全局:

>>> def f(): 
...  print(1) 
...  global f 
...  f=lambda: print(2) 
... 
>>> f() 
1 
>>> f() 
2 
>>> f() 
2 
1

什么你所描述的那种问题缓存被发明了。为什么不只是有一个缓冲区来保存结果;在进行昂贵的计算之前,检查缓冲区是否已经填满;如果是,则返回缓冲结果,否则执行计算,填充缓冲区,然后返回结果。无需为自己修改代码而喜欢它。

+0

他说出真相。阿门(+1)。 – jkp

5

只需在f函数的开头添加global f,否则python会创建一个局部f变量。