Levi
Levi

Reputation: 77

python decorating recursive function

I'm trying to use my timer_func decorator to log the process time of fibonacci function. But It seems like the decorator is logging multiple times:

def timer_func(func):
    def inner_func(*args):
        t1 = perf_counter()
        res = func(*args)
        t2 = perf_counter()
        logging.log(logging.INFO, f"Done in {t2 - t1} Seconds!")
        return res

    return inner_func


@timer_func
def fibonacci(x: int):
    if x > 2:
        return fibonacci(x - 1) + fibonacci(x - 2)
    elif x == 1 or x == 2:
        return 1


r = timer_func(fibonacci)(5)
print("Fibonacci %d of is %d" % (5, r))

Output:

Done in 7.269991328939795e-07 Seconds!
Done in 7.840008038328961e-07 Seconds!
Done in 0.00013806700007990003 Seconds!
Done in 0.0006901449996803422 Seconds!

Upvotes: 0

Views: 199

Answers (2)

Souren Ghosh
Souren Ghosh

Reputation: 96

Even after decorating the function with @ you are again decorating just

r = fibonacci(5)

will do.

Upvotes: 0

0x5453
0x5453

Reputation: 13599

The log will happen each time the fibonacci function is called. Since the function is recursive, it is getting called multiple times.

You'll need to make a second version of the function that has the decorator and calls the non-decorated function. For example:

@timer_func
def fibonacci(x: int):
    return _fibonacci(x)


def _fibonacci(x: int):
    if x > 2:
        return _fibonacci(x - 1) + _fibonacci(x - 2)
    elif x == 1 or x == 2:
        return 1

Upvotes: 3

Related Questions