2015-12-02 65 views
1

我有下面的代码python装饰器如何与递归一起工作?

def memo(fn): 
    cache = {} 
    miss = object() 
    print 'MEMO' 
    def wrapper(*args): 
     result = cache.get(args, miss) 
     print 'IT CALLS' 
     if result is miss: 
      print 'IT MISSES' 
      result = fn(*args) 
      cache[args] = result 
     return result 
    return wrapper 

@memo 
def fib(n): 
    if n < 2: 
     return n 
    return fib(n - 1) + fib(n - 2) 

当我打电话FIB(4)它打印MEMO只有一次。以下是输出。

MEMO 
IT CALLS 
IT MISSES 
IT CALLS 
IT MISSES 
IT CALLS 
IT MISSES 
IT CALLS 
IT MISSES 
IT CALLS 
IT MISSES 
IT CALLS 
IT CALLS 

是什么导致了这种行为?

+0

可能是非相关的,但您可能想要使用(fib(n),fib(n-1))的元组作为fib函数的返回值来使用fib的线性计算。 – DainDwarf

+0

你真的想阅读[this excellent answer]的所有*(https://stackoverflow.com/a/1594484/100297)。 –

回答

3

这是正确的行为,与递归无关。

当装饰器被调用时会打印MEMO,当它被应用于函数时会发生;即在定义时间。如果你从来没有打电话给fib(),MEMO仍然会被打印。

2

你只打印MEMO申请装饰。它不是wrapper函数的一部分,这是装饰器生成的用于替换原始函数的部分。