【发布时间】:2012-06-01 05:45:50
【问题描述】:
我很难理解修饰的递归函数是如何工作的。 对于以下sn-p:
def dec(f):
def wrapper(*argv):
print(argv, 'Decorated!')
return(f(*argv))
return(wrapper)
def f(n):
print(n, 'Original!')
if n == 1: return(1)
else: return(f(n - 1) + n)
print(f(5))
print
dec_f = dec(f)
print(dec_f(5))
print
f = dec(f)
print(f(5))
输出是:
(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15
((5,), 'Decorated!')
(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15
((5,), 'Decorated!')
(5, 'Original!')
((4,), 'Decorated!')
(4, 'Original!')
((3,), 'Decorated!')
(3, 'Original!')
((2,), 'Decorated!')
(2, 'Original!')
((1,), 'Decorated!')
(1, 'Original!')
15
第一个打印 f(n),所以每次递归调用 f(n) 时它都会自然打印 'Original'。
第二个打印 def_f(n),所以当 n 被传递给包装器时,它递归地调用 f(n)。但是包装器本身不是递归的,因此只打印了一个“装饰”。
第三个让我很困惑,这和使用装饰器@dec 是一样的。为什么装饰的 f(n) 也会五次调用包装器?在我看来 def_f=dec(f) 和 f=dec(f) 只是绑定到两个相同函数对象的两个关键字。当装饰函数与未装饰函数的名称相同时,是否会发生其他事情?
谢谢!
【问题讨论】:
-
对原始
f函数的引用仍然存在,因此调用了那个。当您执行f = dec(f)时,您将始终调用新函数。而新的函数会调用原来的函数。 -
decorator可能不是在这里使用的正确术语,因为您实际上从未将装饰器应用于函数。您对f = dec(f)的最后一次测试几乎(如果不完全)与@dec def f相同
标签: python recursion decorator