У меня проблемы с возвратом декораторов. Я хотел бы создать декоратор для расчета времени выполнения функции, поэтому я создаю этот код, чтобы научиться работать с декораторами.
Когда я использую декоратор с методом печати, он работает, но целью этого кода является возврат сообщения с указанием имени функции и продолжительности.
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')
Итак, у меня есть две проблемы:
1 - Если функция что-то возвращает, декораторы не возвращают функцию;
2 - Декораторы просто печатают ответ, он не возвращает его, поэтому я могу повторно использовать ответ.
Если я попытаюсь напечатать результат с этим запросом: ``` print(timer(calculator())) print(timer2(my_name('Leonardo'))) ``` Ответ: <function timer.<locals> .wrapper по адресу 0x0000025D614E5040> Здравствуйте, меня зовут Леонардо <функция timer2.<locals>.wrapper по адресу 0x0000025D614E5040> И я до сих пор не знаю продолжительность функции.
Просто сделайте print(calculator()) — timer уже было применено к функции через строку @timer прямо над ней.






Взгляните на 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
Затем,
calculator() # What do you do with the return value?
my_name('Leonardo')
На самом деле timer2 должно быть точно таким же, как timer. Нет необходимости создавать новую функцию.
Когда вы используете calculator(), проверьте возвращаемое значение, и вы увидите, что оно работает:
res = calculator()
print(res)
Изменение возврата без функции str() и печать украшенной функции вместо печати декоратора сработала. Теперь мне нужно знать, как вернуть результат функции и результат декоратора.
Итак, ребята, это код, который я переделал с вашей помощью, и теперь он работает.
import time
def timer(function):
def wrapper(*args, **kwargs):
init_time = time.time()
funcReturn = function(*args, **kwargs)
end_time = time.time()
result_time = end_time - init_time
if funcReturn == None:
response = {"FunctionName":function.__name__, "TimeSpent":"{:.5f}".format(result_time)}
return response
else:
response = {"FunctionReturn":funcReturn, "FunctionName":function.__name__, "TimeSpent":"{:.5f}".format(result_time)}
return response
return wrapper
@timer
def calculator():
soma_tot = 0
for i in range(1,1000000):
soma_tot += 1
return soma_tot
@timer
def my_name(Name):
print(f'Hello, my name is {Name}')
print(calculator())
print(my_name('Leonardo'))
Таким образом, я получаю результат функции (печать или возврат) и получаю время выполнения функции.
Спасибо всем.
Вы ничего не делаете с возвращаемыми значениями ваших двух функций, поэтому не имеет значения, что возвращает декоратор — значение никуда не денется.