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

Unlock This Lesson

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

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

User-Defined Classes

00:00 In the previous lesson, I showed you how len() works with multi-dimensional NumPy arrays and Panda’s DataFrames. In this lesson, I’ll show you how an object can report back its length through the __len__() special method. Everything in Python is a class.

00:16 All operations in Python map to a special method on a class. These special methods are denoted with prefix and suffix double underscores (__), quickly called dunder methods.

00:27 You’ve probably used the __init__() special method to initialize your own classes. The len() function calls __len__() on whatever object is passed to it.

00:38 As such, you can write your own objects that return lengths. Let’s go play with one.

00:45 In the top half of the window here is a class called Inventory. It behaves kind of like a dictionary in that it stores keys and values. It expects the values to be an integer specifying how many items of a given name there are. The __len__() method then returns the total number of items in the inventory.

01:05 Lines three through eight initialize the object. The contents of the inventory are stored in a dictionary called self.content. Initial content can be passed into Inventory when it is created, and lines six through eight copy that initial data into the content dictionary. Note the use of initial=None on line three. Default arguments in Python should only ever be static values.

01:30 Using a dynamic value like an empty dictionary can cause surprising side effects. If you did that, the second time you created Inventory, you’d get data from the first time you created Inventory. Best not to do that.

01:43 Hence the use of None and a clean dictionary to make sure. The add() method on lines 10 and 11 adds a new item to the Inventory.

01:53 Line 13 is the definition of __repr__(). This is a special method returning a string representation of the object. __repr__() and its cousin __str__() are used by Python to help show the string representations of objects in a couple different cases. They’re commonly used when you’re debugging.

02:13 __repr__() is the one that’s called by the REPL to show its contents, and seeing as I’m going to be demoing this in the REPL, I implemented this so you could see the underlying content of the Inventory.

02:26 And finally, the magic you came here for is on lines 16 and 17. This is the __len__(). This method uses sum() to count up all of the items inside of the internal dictionary and returns that value.

02:41 Let’s take this for a spin … importing the class …

02:50 creating some inventory for my fruit market …

02:59 showing the value. This is where the __repr__() method is called. And now what you came here for: len() Sure enough, three and five is eight. Aren’t computers wonderful? In the olden days, you would have had to use your fingers or something to do that kind of math.

03:17 __len__() has added up the number of apples and the number of pears and returned the total result. I think I missed out on an opportunity here about apples and oranges being compared. By implementing __len__(), you have also by default made your object truthy.

03:36 Converting to a Boolean by calling the bool() function determines the length, gets a number bigger than zero, and uses that to determine True. I can do that again with an empty inventory.

03:54 And this time you get False. Implementing __len__() gives you both the length and truthiness. If you don’t like this behavior, you can also override __bool__() and get it to do what you want instead.

04:09 In the immortal words of Forrest Gump, “And that’s all I have to say about that.” Last stop, I summarize the course.

Become a Member to join the conversation.