我很難理解裝飾遞歸函數的工作原理。 對於下面的代碼片斷:在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'差不多(如果不完全一樣) –