Reputation: 3359
I cant't for the life of me figure out how to make this into a decorator. Any help or an example would be awesome.
Here is the code
import datetime
def time_func(function, *args, **kwargs):
'''
Add the execution time to a functions attributes
'''
# Start the clock.
start = datetime.datetime.now()
# Execute the function and record the results.
function_result = function(*args, **kwargs)
# Calculate the elapsed time and add it to the function
# attributes.
function.elapsed = datetime.datetime.now() - start
# Returned the function with the added elapsed attribute
return function_result
Here is an example use
.. import datetime
..
..
.. def time_func(function, *args, **kwargs):
.. '''
.. Add the execution time to a functions attributes
.. '''
.. # Start the clock.
.. start = datetime.datetime.now()
.. # Execute the function and record the results.
.. function_result = function(*args, **kwargs)
.. # Calculate the elapsed time and add it to the function
.. # attributes.
.. function.elapsed = datetime.datetime.now() - start
.. # Returned the function with the added elapsed attribute
.. return function_result
..
..
.. def f(name):
.. print name
..
.. time_func(f, 'foo')
.. print f.elapsed
..
foo
0:00:00.000115
Upvotes: 0
Views: 1426
Reputation: 104712
A common way to make decorators is to use two nested functions:
def time_func(function):
def wrapper(*args, **kwargs):
start = datetime.datetime.now()
function_result = function(*args, **kwargs)
wrapper.elapsed = datetime.datetime.now() - start
return function_result
return wrapper
The only major between this code and your original (other than stripping out the comments for space) is that the function
is supplied by a call to the outer function while the other arguments are supplied to the wrapper function. We also need to save the elapsed
time on the wrapper
function instead of the original function (since the original will not be accessible any more when you a decorator).
Upvotes: 0
Reputation:
A decorator is simply a function that takes a function and returns a function.
import datetime
def time_func(function):
# create a new function based on the existing one,
# that includes the new timing behaviour
def new_func(*args, **kwargs):
# Start the clock.
start = datetime.datetime.now()
# Execute the function and record the results.
function_result = function(*args, **kwargs)
# Calculate the elapsed time and add it to the function
# attributes.
new_func.elapsed = datetime.datetime.now() - start
# Returned the function with the added elapsed attribute
return function_result
return new_func
Usage:
@time_func
def f(name):
print(name)
f('foo')
print(f.elapsed)
> foo
> 0:00:00.000045
Check out functools.wraps
to further improve the decorator.
Upvotes: 2
Reputation: 42758
Define an inner function:
import datetime
def time_func(function):
'''
Add the execution time to a functions attributes
'''
def func(*args, **kwargs):
start = datetime.datetime.now()
function_result = function(*args, **kwargs)
func.elapsed = datetime.datetime.now() - start
return function_result
return func
@time_func
def f(name):
print name
Upvotes: 2