为什么这个python函数中需要一行?(记忆递归)

为什么这个python函数中需要一行?(记忆递归),python,recursion,decorator,Python,Recursion,Decorator,我从Peter Norvig的网站上获得了以下代码片段:;它是一个decorator,用于启用函数调用的记忆(缓存之前对函数的调用,以将指数递归更改为简单的动态程序) 代码运行良好,但我想知道为什么需要倒数第二行。这显然是我对Python知识的一个空白,但是去掉这一行并运行一个简单的斐波那契函数,它似乎仍然有效。这与同时记忆多个函数有关吗?为什么fmemo的成员变量被称为memo(假设这不是一个尴尬的巧合) 谢谢 因为函数和其他任何东西一样都是对象,所以可以对它们设置属性。见: >>

我从Peter Norvig的网站上获得了以下代码片段:;它是一个decorator,用于启用函数调用的记忆(缓存之前对函数的调用,以将指数递归更改为简单的动态程序)

代码运行良好,但我想知道为什么需要倒数第二行。这显然是我对Python知识的一个空白,但是去掉这一行并运行一个简单的斐波那契函数,它似乎仍然有效。这与同时记忆多个函数有关吗?为什么fmemo的成员变量被称为memo(假设这不是一个尴尬的巧合)


谢谢

因为函数和其他任何东西一样都是对象,所以可以对它们设置属性。见:

>>> def foo(): pass
>>> foo.x = 1
>>> foo.x
1
第二行将值的内部缓存设置为函数对象上的属性,从而公开它。这意味着您可以使用一个已记录的函数,随意摆弄它的缓存,而无需调用它。这可能很方便


例如:

>>> @memo
... def id(x): return x
>>> id(1)
1
>>> id(2)
2
>>> id.memo
{(2,): 2, (1,): 1}

代码的缩进看起来不正确。这是一个嵌套函数吗?顺便说一句,这在Python3.2中已经实现为。@MAK:这是一个嵌套函数。这是一份声明decorator@Bean:缩进已在我的评论后修复。我的错!一定是一个错误的复制/粘贴。我想补充一点,这是没有必要的,因为关闭。正如您所说,不需要调用它就可以对其进行干预或访问值的能力将是非常重要的。事实上,closed-over
table
变量也会对缓存进行命名(如果
memo
在外部重新分配,这实际上是有问题的)。。。但是+1。事实上,重新分配
memo
是不好的。@Bean:corrent;一般来说,你不能看别人的范围。这就是示波器的用途@Bean:您可以查看函数的func_闭包元组。
>>> @memo
... def id(x): return x
>>> id(1)
1
>>> id(2)
2
>>> id.memo
{(2,): 2, (1,): 1}