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

Enhancing the Timer Class

Resource mentioned in this lesson: Data Classes in Python (Guide)

00:00 Our Timer class is now in a very good spot to be brought to the next level, which is going to be something called a context manager. But before there, we need to go to sort of a middle ground, which is going to be converting it to a data class.

00:14 There are some conveniences of data classes. I won’t be able to get into everything today, so do check out our tutorial on data classes. For now, let’s see our Timer class and how we can alter it to get it ready for the context manager.

00:31 Here I have a file called enhanced_timer.py, and there’s a lot of new stuff that is going on here. Even though there’s a lot of changes going on, the functionality and the implementation is essentially the same under the hood.

00:45 Let’s go through it. At the very top, I’m importing from the dataclasses module, dataclass and field. I’m also importing typing, which is a whole other topic, which I won’t be having much time to get into today. But for the most part, it’s going to be required for us using data classes. We’re importing time still.

01:03 We’re still having our TimerError class. And here’s where we see a big difference. In our Timer class, right above it, the first line right above it, we have this at sign and dataclass.

01:14 This little at symbol is denoting that this is actually what’s called a decorator, which is a whole other cool component of what we could convert our Timer class into.

01:25 But we won’t be getting again into that today. There’s some tutorial stuff on that as well. So I definitely will recommend that at the end. For now, we’re sort of seeing right away some differences.

01:36 We still have our timers dictionary being defined here as a class variable. However, you’ll notice that our other .__init__() method properties are sort of being defined here.

01:48 And I say properties, but they were essentially the parameters, but they were also the properties. And this is one of the conveniences of having a data class where before we had this sort of boilerplate where we had the parameter defined, we had to reference it and then store it internally by the exact same name.

02:06 And essentially, we were using the same name three different times. But here, we just define it once and it works the exact same way that you think it does. We can define name here and essentially it will be one of the parameters for .__init__() and it will be stored internally as the same name.

02:21 So we have name, text, and logger working exactly the same way as it was before. And the _start_time is there as well. Now, one difference you’ll notice here is the .__post_init__() method, which is essentially the post-init, which works like you might think it does.

02:40 Right after the initialization, this is arbitrary code you can run. In this case, this is the same code that we were running before. We’re checking for name and then setting the default timer key-value pairing.

02:51 So that essentially is the same .__init__() function working the same way it was before. Our .start() method is unchanged.

03:00 And our .stop() method is unchanged. So I’m going to showcase how this works. And for the most part, it won’t be very different from what it was before. So here I am in the terminal again.

03:11 I always like to check my files. And here we have our enhanced_timer.py file. Let’s go into Python.

03:18 Let’s import from

03:22 enhanced_timer.

03:24 Import that Timer class, but it’s a data class. But what’s interesting is that data classes are just classes. It’s just sort of like sprinkling a little enhancement on it, but it just makes it look nice. But it’s still a class under the hood.

03:36 Let’s go with t1 = Timer. And I’ll call it ("test1") again.

03:43 t1.start(). And let’s say .stop().

03:48 And we see that Timer.timers, it’s still there. Everything is working the same way it was before. We can do a new timer.

03:59 t2 = Timer("test2"). t2.start(). And t2.stop(). And Timer.timers. It’s all there. I mean, everything is working the exact same way.

04:12 You might be wondering, well, what’s the point? Why would we do all that work to change it? Besides the convenience of removing some boilerplate, this is a requirement for us setting up or being a context manager.

04:23 Speaking of which, let’s check out context managers next.

Become a Member to join the conversation.