Непосредственная проблема заключается в том, что wed
не возвращает возвращаемое значение func
. Это легко исправить.
def time_cost(func):
def wed(n):
start = time.time()
<b>n = </b>func(n)
stop = time.time()
print(stop-start)
<b>return n</b>
return wed
Однако, теперь посмотрите, что происходит, когда вы звоните R_F(3)
.
>>> R_F(3)
9.5367431640625e-07
1.1920928955078125e-06
0.0001671314239501953
2
Вы получаете 3 раз: по одному на рекурсив вызов. Это происходит потому, что исходная функция вызывает то, с чем связана R_F
, которая теперь является функцией wed
, а не фактической функцией Фибоначчи.
Нечто подобное лучше обрабатывать с помощью диспетчера контекста.
from contextlib import contextmanager
@contextmanager
def time_cost():
start = time.time()
yield
stop = time.time()
print(stop - start)
with time_cost():
R_F(3)
Отступление
В некотором смысле Python не имеет рекурсивных функций. Функция не может вызывать сама себя, а только некоторая функция, связанная с именем, которое вы ожидаете , будет ссылаться на вашу функцию. Назовите это «кооперативная рекурсия».
Например, рассмотрим стандартный пример рекурсивной функции, факториал.
def fact(x):
return 1 if x == 0 else x * fact(x-1)
Мы можем легко сломать это, связав имя fact
.
g = fact # save a reference to the original function
def fact(x):
print("Broken")
return 0
Теперь g(3)
печатает Broken
и возвращает 0, потому что он попытается вызвать все, что fact
связано с сейчас , а не то, с чем fact
было связано прежде чем переопределить его.
Если вы хотите "безопасную" рекурсивную функцию, вам придется определить ее в терминах частного рекурсивного помощника.
def fact(x):
def helper(x):
return 1 if x == 0 else x * helper(x - 1)
return helper(x)
Теперь вы можете безопасно декорировать fact
, потому что независимо от того, с чем связан fact
(будь то оригинал или декорированная функция), helper
никогда не восстанавливается.