Reputation: 950
I would like to wrap some code around a function (e.g. print timing information) and reuse this function for multiple code blocks:
start = time.time()
print('Started adding numbers at {}'.format(start))
a = 1
b = 2
c = a + b
end = time.time()
print('Finished adding numbers in {} seconds'.format(end - start)')
Is it possible to wrap multiple lines of code into a wrapper function, without defining functions for each code blocks? One way would be to define a function and use a decorator but I would like to avoid doing this for every code block:
@print_time
def foo():
a = 1
b = 2
return a + b
Upvotes: 1
Views: 1180
Reputation: 944
One other way is to use context managers.
For example:
from contextlib import contextmanager
@contextmanager
def timer():
start = time.time()
print('Started adding numbers at {}'.format(start))
yield
end = time.time()
print('Finished adding numbers in {} seconds'.format(end - start))
# Then call it like that
with timer():
a = 1
b = 2
c = a + b
Upvotes: 1
Reputation: 177
You could create a context manager class and execute your code in a with block. This would make for a compact and highly reusable timer function. Something like this:
import time
class TimeClass():
def __init__(self):
pass
def __enter__(self):
self.start = time.time()
def __exit__(self, type, value, traceback):
self.end = time.time()
print('Finished executing in {} seconds'.format(self.end - self.start))
You could use the class like this:
with TimeClass():
# your code
pass
Check this link out for more details.
Upvotes: 3
Reputation: 1840
Alternative what do you think about this:
You define a timer class, that keeps timers in store by name e.g. Description for the code block, and put all the prints and dos you like as optins in the stop_timer function. It is still two lines of code, but I dont think you will get less then that
import time as t
class myTimer:
def __init__(self):
self.timers = {}
def start_timer(self, name):
print('Started adding numbers at {}'.format(t.time()))
self.timers[name] = t.time()
def stop_timer(self,name):
runtime = t.time() - self.timers[name]
del(self.timers[name])
print('Finished adding numbers in {} seconds'.format(runtime))
return runtime
timer = myTimer()
timer.start_timer('First Timer')
timer.start_timer('Second Timer')
a = 1
t.sleep(1)
b = 2
timer.stop_timer('First Timer')
c = 3
t.sleep(2)
d = 4
timer.stop_timer('Second Timer')
Returns
Started adding numbers at 1606676633.8297324
Started adding numbers at 1606676633.8297324
Finished adding numbers in 1.0228865146636963 seconds
Finished adding numbers in 3.0250420570373535 seconds
Upvotes: 1
Reputation: 1840
Yu can do this using higher order functions such as:
def inner():
pass
def outer(inner):
inner()
and then call
outer(inner)
Upvotes: 0