我很难理解装饰递归函数的工作原理。 对于下面的代码片断:在Python中装饰递归函数
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)被递归调用。
第二个打印def_f(n),所以当n传递给包装时,它会递归地调用f(n)。但包装本身不是递归的,所以只打印一个'装饰'。
第三个令我困惑,这和使用装饰者@dec一样。为什么装饰的f(n)也会调用wrapper五次?在我看来,def_f = dec(f)和f = dec(f)只是绑定到两个相同函数对象的两个关键字。当装饰的功能与未修饰的功能具有相同的名称时,是否还有其他内容?
谢谢!
参考原来的'F'功能仍然存在里面,这样一个被称为看到这一点。当你做'f = dec(f)'时,你将总是调用新的函数。新功能将调用原始文件。 – JBernardo
'装饰器'可能不是在这里使用的正确术语,因为你从来没有真正将装饰器应用到函数中。你最后一次测试'f = dec(f)'与'@dec def f'差不多(如果不完全一样) –