2011-12-17 81 views
12

我从Peter Norvig的网站获得了以下代码片段;它是一个装饰器,用于启用函数调用的memoization(缓存之前调用该函数以将指数递归转换为简单的动态程序)。为什么在这个python函数中有一行是必需的? (memoized递归)

def memo(f): 
    table = {} 
    def fmemo(*args): 
     if args not in table: 
      table[args] = f(*args) 
     return table[args] 
    fmemo.memo = table 
    return fmemo 

该代码工作正常,但我想知道为什么倒数第二行是必要的。这显然是我对Python的知识上的一个缺陷,但是删除了这一行并运行了一个简单的斐波那契函数,它似乎仍然有效。这是否与同时记忆多个功能有关?为什么fmemo的成员变量被称为备忘录(假设它不是一个尴尬的巧合)?

谢谢!

+0

代码的缩进看起来不正确的。这是一个嵌套函数吗? – MAK 2011-12-17 02:15:49

+0

FTFY ........... – katrielalex 2011-12-17 02:17:55

回答

12

由于函数与其他任何东西都是对象,所以可以在它们上设置属性。请参阅:

>>> 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}