Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:从函数内部重新定义函数_Python - Fatal编程技术网

Python:从函数内部重新定义函数

Python:从函数内部重新定义函数,python,Python,我有一些昂贵的函数f(x),我只想计算一次,但调用频率相当高。本质上,第一次调用该函数时,它应该计算x范围内的一整组值,因为它无论如何都会被积分,然后用样条插值,并以某种方式缓存系数,可能在文件中以供进一步使用 我的想法是做如下的事情,因为它很容易实现。第一次调用函数时,它会做一些事情,然后重新定义自己,然后再做其他事情。然而,它并没有像预期的那样工作,而且通常可能是不好的做法 def f(): def g(): print(2) print(1) f =

我有一些昂贵的函数f(x),我只想计算一次,但调用频率相当高。本质上,第一次调用该函数时,它应该计算x范围内的一整组值,因为它无论如何都会被积分,然后用样条插值,并以某种方式缓存系数,可能在文件中以供进一步使用

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

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中的值不可散列,它就会崩溃。