Reputation: 13
I am trying to learn how decorators works and how to use them, but I'm getting a strange behavior. The idea is to create a wrapper method to calculate the execution time (I know, have other ways to do this) and wrap a method called "cadastra_usuario_no_banco", this method just get a sleep and returns true.
import time
def tempo_de_execucao(funcao_original):
def envolucro(*args, **kargs):
tempo_inicio = time.time()
retorno = funcao_original(*args, **kargs)
tempo_total = time.time() - tempo_inicio
print(" -------- envolucro --------")
print("A função retornou", retorno)
print(int(tempo_total), "Segundos para a execução")
return envolucro
@tempo_de_execucao
def cadastra_usuario_no_banco():
print ("iniciando cadastro de usuário")
time.sleep(1)
print ("Cadastro de usuário efetuado com sucesso!")
return True
But, when I try to run using the follow instructions
a = tempo_de_execucao(cadastra_usuario_no_banco)
print(a())
I am getting two times the print and returns from the wrapper.
iniciando cadastro de usuário # Execution of the wrapped method
Cadastro de usuário efetuado com sucesso!
-------- envolucro -------- # The decorated execution
A função retornou True # the correct return of the wrapped method
1 Segundos para a execução # the time of the execution
A função retornou None # the strange behavior, that is not supposed to be here
1 Segundos para a execução # is not supposed to be here too
None # the print of the wrapper method (this is correct)
Why this is happening?
Upvotes: 1
Views: 28
Reputation: 641
As stated on the comments and from the docs:
@dec2
@dec1
def func(arg1, arg2, ...):
pass
Is equivalent to
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
Decorators are functions that takes another function as arguments and returns a new function.
So you are calling it twice when you put @tempo_de_execucao
above cadastra_usuario_no_banco
and also called tempo_de_execucao(cadastra_usuario_no_banco)
, which resulted in tempo_de_execucao(tempo_de_execucao(cadastra_usuario_no_banco))
Upvotes: 1