Join us and get access to thousands of tutorials and a community of expert Pythonistas.
This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.
Extending namedtuple Classes
00:00 In the previous lesson, I emceed the big showdown: named tuples against other Python data classes. In this lesson, I’ll show you how to extend a named tuple and why you might do that.
00:12
The namedtuple() factory returns a class. You can inherit from that class to create other classes. Before data classes, this was a common thing to do.
00:22 Now it’s not as important, but given there are memory differences between named tuples and data classes, you might still want to use this idea. The reason to extend a named tuple is to make it more like a plain old data object.
00:34
You can add methods like you would with any other class. To maintain your slim memory profile, there is one thing you have to do, which is set the __slots__ value.
00:45 Python classes normally have a dictionary associated with their underlying implementation. When you change something in the object, it is that dictionary that gets updated.
00:54
When you specify the __slots__ value in a class, you are telling Python that you’re not interested in updating the attributes in the class. This means the dictionary can be optimized away.
01:05
Clever use of __slots__ can lead to faster attribute access and less memory use. For our subclass of named tuple, I’m going to be setting __slots__ to ensure that I keep the memory advantage of the parent class.
01:17 Let’s go look at some code.
01:21
In this code, I’m once again creating a class that represents a person, but this time I’m doing it by subclassing a named tuple. To subclass a named tuple, first, you need a namedtuple class.
01:34
I have called mine _BasePerson and have named it with a leading underscore to indicate that it isn’t supposed to be used outside the module.
01:41
This is a common convention in Python. With the base person ready, I create the new PersonTuple class by extending the base person.
01:52
As I mentioned before, this is the __slots__ value. By setting it to empty, I’m indicating to Python that I don’t need a dictionary associated with this class.
02:01
In a regular class, I’d include the names of the attributes that I was exposing in here, but the namedtuple parent class will handle that, so a blank tuple is good enough.
02:11 This is a bit tricky, and in real code, it really should have a comment explaining what is going on. The rest of the class contains the methods I wanted to add.
02:21
I’m being a bad boy here and having .__repr__() return a string that isn’t very REPL friendly. Best practice with this method is to return something that can be copy and pasted into the REPL to create an equivalent object.
02:33
I’m mucking with this because I’m going to show it off in the REPL. You probably should be better behaved than I am. And finally, I’ve added a property called age that calculates how old the person tuple is by finding the difference between today and their birthdate.
02:49 There are probably edge cases with this calculation, given leap years and things, but it’s good enough to show off what I’m talking about. Let’s see if this works.
03:00 Importing my new class …
03:07
and the date object as person tuple’s .birth attribute expects a date.
03:18
And here I’ve created Juanita, born on December 22, 1999. Since I’m in the REPL, the method called when I display something is .__repr__().
03:29
This would be my rebel string that ignores best practices. And of course, it contains Juanita’s age, so the age property was called to print this string.
03:39
Except for the __slots__ thing, this is like any inheriting from any other class, and even if you forgot the __slots__ thing, you’d still get a class that works.
03:48 It just won’t be as performant as a named tuple.
03:55 That’s pretty much it for named tuples. In the last lesson, I’ll summarize the course and point you at some further investigation.
Become a Member to join the conversation.