I have the following code and the print statement within the perform()
function does not output, what is the reason for this?
from time import time
def perform(fn):
def wrap(*args, **kwargs):
t1 = time()
result = fn(*args, **kwargs)
t2 = time()
print(f'It took {t2 - t1} seconds to execute')
return result
return wrap
@perform
def long_time():
for i in range(100000000):
num = i * 5
CodePudding user response:
If this is your full code, you need to actually run the function.
Add this to your script;
long_time()
CodePudding user response:
Whilst you have defined both functions and your decorator exists that invokes perform()
when long_time()
is called, you have not actually called the long_time()
function itself.
from time import time
def perform(fn):
def wrap(*args, **kwargs):
t1 = time()
result = fn(*args, **kwargs)
t2 = time()
print(f'It took {t2 - t1} seconds to execute')
return result
return wrap
@perform
def long_time():
for i in range(100000000):
num = i * 5
# Call the function and this in turn will invoke the decorator function
# perform() and display the print statement.
long_time()
The reason it doesn't execute immediately with the decorator is because it includes a wrapper function, therefore it needs to be manually invoked itself rather than it being automatically executed.
Decorators Documentation: https://www.python.org/dev/peps/pep-0318/
CodePudding user response:
applying a decorator using the typical decorator style (define wrapped function then return wrapped function and do nothing else) does not call the function. Decorators are basically a shorthand for the following:
def decorate(func):
def wrapped(*args, **kwargs):
return func(*args, **kwargs)
return wrapped
#this
@decorate
def some_other_func(a, b, c):
print(a, b, c)
#is the same as this:
def some_other_func(a, b, c):
print(a, b, c)
some_other_func = decorate(some_other_func)
notice the decorate
function just creates a new function and returns it, but does not call it. Therefore the "decorated" function does not get called unless you then later call it.
If you were to put some functionality outside the "wrapped" function on the other hand, that would get called:
def decorate(foo):
print('this gets executed as soon as the function gets "wrapped" on definition')
def wrapped(*args, **kwargs):
return foo(*args, **kwargs)
return wrapped
@decorate
def some_func():
print("some_func is defined then passed to @decorate")
print("this will be printed after the function is defined and subsequently wrapped by the decorate function")