1

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

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

1

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

Comments

0

Yu can do this using higher order functions such as:

def inner():
    pass

def outer(inner):
    inner()

and then call

outer(inner)

1 Comment

I explicitly noted that I would not like to define additional functions just to wrap code blocks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.