Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Using a Context Manager

00:00 The Timer class is now in a good spot where we can now convert it into a context manager. What’s nice about context managers is that it ensures that your code executes in an ordered fashion.

00:12 Specifically, we want some block of code to run in between, sort of sandwiched between when we start our timer and when we end our timer. A context manager is actually really ideal for that exact scenario.

00:24 For today, I will not be able to get into all of the concepts and implementation of how context managers work. However, we have a tutorial on that. So do go check that out.

00:36 For now, we’re going to be taking our Timer class, which is currently in a data class format, and we’ll be converting it into a context manager.

00:44 What’s nice is that most of the work is already done at this point. One of the nice things I like about context managers is that it helps you clearly visualize the code block that’s being timed because it’s just smack dab in the middle.

00:56 It’s very obvious, kind of removes the need to handle the start and stop within the code. It just works very nicely. So let’s check out how we can implement that.

01:07 So here I have a file called context_manager_timer.py, and it is going to look exactly the same as our data class implementation, except if I go all the way to the bottom, where we have two new methods.

01:22 So these are the two methods that are required to have a context manager. They are .__enter__(), which takes only the self as a parameter, and we can see that our implementation just starts our timer.

01:35 We’re calling the .start() method. That’s it. And what’s interesting is we’re returning the instance itself, and we’ll be seeing how that works in a little bit.

01:43 Lastly, we have the .__exit__() method, which takes the self as a parameter, the first one, and then some exception information.

01:52 We’re not going to go into too much detail on that. I definitely recommend you look that up in case you want to handle certain exceptions because this code, the .__exit__(), will run even if there is an error within the code block that’s running.

02:04 So here we’re going to stop our timer no matter what, if there’s an error or just as we exit the context manager, we’re going to call .stop() to our timer and our .stop() method, if you recall, will actually print the elapsed time to the console.

02:19 So let’s check out how this works in practice.

02:22 All right, here I am in the terminal. Let me always check my files. Here we go. We have the context_manager_timer file. So let me enter Python world here.

02:32 And from that context_manager_timer file, I want to import the Timer class. I’m also going to import the time module just so we have some actual code, some stuff to run in the middle of our code block so that we can actually have something worth timing.

02:52 Mostly going to just call the time.sleep() function. Let’s see how we can implement our Timer class as a context manager. We need the keyword with, and that’s how we begin.

03:03 And we’re going to say with our Timer instance, I’m going to then enter and you’ll see that I’m tabbed in because we’re now in the context of the Timer instance.

03:15 And what we can do here is basically anything we want. So whatever we put here is going to be running after we started or entered the context manager. I’m going to call time.sleep().

03:26 We’ll sleep for five seconds. And once I hit Enter here, I’m going to hit it twice. But once I hit Enter, well, first we’ll wait five seconds and then we’ll see the call to the .__exit__() method be called.

03:37 So let’s see that now. Well, I guess we’ll wait five seconds and then we should see it print out elapsed time. There we go. Perfect. So this is working as you might expect. I want to show you also how we can work with that call to .__enter__(), a dunder method, which is when we instantiate the instance.

03:56 So let’s say Timer. We can actually give these timers names. So let’s call this one "timer1". And let’s say now we have the timer.

04:06 But what about the instance? How do we handle that? So this is actually going to get returned and we can say Timer, as, and whatever variable we put here will be our timer.

04:16 I’m going to call it t1. When I press Enter here, we are now again in the context and we can actually use that variable t1 because that’s a reference to the instance that we’ve created.

04:28 So I’m going to actually print t1.name because that’s a property that it should have. So it’ll print timer1 essentially. I’m also going to do time.sleep() and basically any other code. This is the practical implementation.

04:42 Whatever code you want to time, this is where you’d put it. And once you exit, it automatically exits the timer and stops it. So let’s press Enter here. We see timer1 be printed.

04:53 We’re waiting five seconds. It should exit and then it should say elapsed time five seconds. Perfect. Now, one more thing I want to show you is what happens if there’s some error or some kind of exception that happens within the code block, not within the timer function, but within this code that’s being timed.

05:08 What happens then? So let’s say with Timer, I’ll call this one "timer2" as t2 and we can say print().

05:17 I want to print Timer.timers so we can see the dictionary and let’s do some time.sleep(). Let’s sleep for five seconds and then I want to create an error. I’m going to do a division by zero error.

05:31 One divided by zero is impossible, but that will error out. So what’s going to happen, we’re going to obviously start the context manager. We’re going to print the timers dictionary, wait five seconds, and then when we get to the error, our context manager will close or it will exit and it will call the .__exit__() code.

05:49 So it will stop the timer. Let’s see that happen here. We’ve got our dictionary, wait five seconds, we should see it exit with the elapsed time. You’ll see elapsed time happen and then we see the ZeroDivisionError.

06:03 There is a lot you can do with context managers. We’re definitely not going to cover all of that, but I think we’re in a good spot to leave it here. So let’s just review what we’ve been going over.

Become a Member to join the conversation.