Search code examples
pythondecorator

Problems with python decorators returns


I'm having some problems with the decorators return. I would like to create a decorator to calculate the function duration time, so I build this code to learn how to work with decorators.

When I use the decorator with the print method, it works, but the intention of this code is to return the message saying the function name and the duration time.

import time

def timer(function):
    def wrapper(*args, **kwargs):
        init_time = time.time()
        res = function(*args, **kwargs)
        end_time = time.time()
        Answer = str(f'The function {function.__name__} takes {end_time - init_time} seconds to be executed.')
        print(Answer)
        return res
    return wrapper

def timer2(function):
    def wrapper(*args, **kwargs):
        init_time = time.time()
        function(*args, **kwargs)
        end_time = time.time()
        Answer = str(f'The function {function.__name__} takes {end_time - init_time} seconds to be executed.')
        return Answer
    return wrapper

@timer
def calculator():
    soma_tot = 0
    for i in range(1,1000000):
        soma_tot += 1
    return soma_tot

@timer2
def my_name(Name):
    print(f'Hello, my name is {Name}')

calculator()
my_name('Leonardo')

So I got two problems:
1 - If the function return something, the decorators is not returning the function return;
2 - The decorators just print the answer, it's not returning it so I can reuse the answer.


Solution

  • Take a look at timer2:

    def timer2(function):
        def wrapper(*args, **kwargs):
            init_time = time.time()
            function(*args, **kwargs)  # Where does the result go?
            end_time = time.time()
            Answer = str(f'The function {function.__name__} takes {end_time - init_time} seconds to be executed.')
            return Answer  # You return an unrelated string
        return wrapper
    

    Then,

    calculator()  # What do you do with the return value?
    my_name('Leonardo')
    

    In fact, timer2 should be exactly like timer. No need to create a new function.

    When you use calculator(), check the return value and you'll see it works:

    res = calculator()
    print(res)