Python:从函数内部重新定义函数
我有一些昂贵的函数f(x),我只想计算一次,但调用频率相当高。本质上,第一次调用该函数时,它应该计算x范围内的一整组值,因为它无论如何都会被积分,然后用样条插值,并以某种方式缓存系数,可能在文件中以供进一步使用 我的想法是做如下的事情,因为它很容易实现。第一次调用函数时,它会做一些事情,然后重新定义自己,然后再做其他事情。然而,它并没有像预期的那样工作,而且通常可能是不好的做法Python:从函数内部重新定义函数,python,Python,我有一些昂贵的函数f(x),我只想计算一次,但调用频率相当高。本质上,第一次调用该函数时,它应该计算x范围内的一整组值,因为它无论如何都会被积分,然后用样条插值,并以某种方式缓存系数,可能在文件中以供进一步使用 我的想法是做如下的事情,因为它很容易实现。第一次调用函数时,它会做一些事情,然后重新定义自己,然后再做其他事情。然而,它并没有像预期的那样工作,而且通常可能是不好的做法 def f(): def g(): print(2) print(1) f =
def f():
def g():
print(2)
print(1)
f = g
f()
f()
预期产出:
1
2
实际产量:
1
1
在f()之外定义g()没有帮助。为什么这不起作用?除此之外,我现在能想到的唯一解决方案就是使用一些全局变量。或者为此编写一个类有意义吗?在f的作用域中更改f不会影响函数的外部,如果要更改f,可以使用全局:
>>> def f():
... print(1)
... global f
... f=lambda: print(2)
...
>>> f()
1
>>> f()
2
>>> f()
2
您所描述的是缓存是为解决这类问题而发明的。为什么不只是有一个缓冲区来保存结果;在进行昂贵的计算之前,检查缓冲区是否已填满;如果是,则返回缓冲结果,否则,执行计算,填充缓冲区,然后返回结果。无需对此进行自我修改代码。只需在f函数的开头添加
全局f
,否则python会创建一个局部f变量。这太复杂了。相反,使用备忘录:
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
在Python3中,您可以将
已记忆的替换为。您可以使用和缓存结果。请看一个例子。关于回忆录的另一个问题可能被证明是有用的。他说的是事实。阿门(+1)。+1:而且,在允许装饰的Python版本中,这是一条路要走。典型的例子。你不觉得dict是不可破坏的吗?@juanchopanza,是的。删除了参数,因为在本例中它们无论如何都是不必要的。@phihag我希望有一个简单的内置解决方案来记忆**kwargs@juanchopanza好吧,您可以随时将项目转换为冻结集
,但只要args/kwargs中的值不可散列,它就会崩溃。