Extending Built-in Functions

Learn how can we add additional functionalities in our classes.

One interesting use of this kind of inheritance is adding functionality to built-in classes. In the Contact class seen earlier, we are adding contacts to a list of all contacts. What if we also wanted to search that list by name? Well, we could add a method on the Contact class to search it, but it feels like this method actually belongs to the list itself.

Example 1

The following example shows how we can do this using inheritance from a built-in type. In this case, we’re using the list type. We’re going to inform mypy that our list is only of instances of the Contact class by using list["Contact"]. For this syntax to work in Python, we need to also import the annotations module from the __future__ package. The definitions look like this:

Press + to interact
from __future__ import annotations
class ContactList(list["Contact"]):
def search(self, name: str) -> list["Contact"]:
matching_contacts: list["Contact"] = []
for contact in self:
if name in contact.name:
matching_contacts.append(contact)
return matching_contacts
class Contact:
all_contacts = ContactList()
def __init__(self, name: str, email: str) -> None:
self.name = name
self.email = email
Contact.all_contacts.append(self)
def __repr__(self) -> str:
return (
f"{self.__class__.__name__}("
f"{self.name!r}, {self.email!r}" f")"
)

Extend superclass’ list

Instead of instantiating a generic list as our class variable, we create a new ContactList class that extends the built-in list data type. Then, we ...