It’s common to want to time a piece of code. In Python, the with
statement provides a convenient way to do so.
If you’ve followed my previous post, The Python with Statement by Example, you should have no problem following along here. All you need is a class which implements the __enter__
and __exit__
methods:
import time class Timer: def __enter__(self): self.start = time.clock() return self def __exit__(self, *args): self.end = time.clock() self.interval = self.end - self.start
Of course, this is not a revolutionary idea. We’re just subtracting a couple of time.clock
calls. If you google around, you’ll find several people suggesting to use the with
statement in the same way. I’ve only tweaked the implementation details.
In the above class, the __enter__
method returns the Timer
object itself, allowing us to assign it to a local variable using the "as" target
part of the with
statement. So we can write the following:
import httplib with Timer() as t: conn = httplib.HTTPConnection('google.com') conn.request('GET', '/') print('Request took %.03f sec.' % t.interval)
The main advantage of using the with
statement is that the __exit__
method will be called regardless of how the nested block exits. Even if an exception is raised in the middle of the nested block – as would happen if network problems interfere with the above HTTPConnection
– the __exit__
method will be called. To see the result, though, we’d have to handle the exception in a try/finally
block:
try: with Timer() as t: conn = httplib.HTTPConnection('google.com') conn.request('GET', '/') finally: print('Request took %.03f sec.' % t.interval)
Now, even if your network cable comes unplugged, you’ll still see the running time of this code.
Of course, Python has its own set of debugging and profiling modules in the standard library. Use whatever suits your purpose.