Jan 1, 2022
I often want to create objects that hold several related pieces of data together in the same place - like a Book object that has an author, title, etc. Python offers several methods to do this, but it's not always clear which one to use. I'll show different patterns that I use and discuss the advantages and disadvantages of each.
I call these container classes because they're mostly used to hold information.
| Name | Description | 
|---|---|
| Vanilla Class | A plain Python class | 
| Dictionary | A plain Python dictionary | 
| Typed Dictionary | A Python dictionary plus a TypedDictschema | 
| SimpleNamespace | A Python namespace object | 
| NamedTuple | A tuple with names, from the collectionsmodule | 
| Dataclass | A container class from the dataclassesmodule | 
| attrsClass | The only non-standard-library solution, from the attrslibrary | 
class Book:
    """Container class for a Book and its attributes."""
    def __init__(
        self,
        author: str,
        title: str,
        publication_year: int,
        isbn_10: Optional[str],
        isbn_13: Optional[str],
    ) -> None:
        self.author = author
        self.title = title
        self.publication_year = publication_year
        self.isbn_10 = isbn_10
        self.isbn_13 = isbn_13
brothers_karamazov = Book(
    author="Fyodor Dostoevsky",
    title="The Brothers Karamazov",
    publication_year=1880,
    isbn_10="0374528373",
    isbn_13="978-0374528379",
)
brothers_karamazov: Book = {
    "author": "Fyodor Dostoevsky",
    "title": "The Brothers Karamazov",
    "publication_year": 1880,
    "isbn_10": "0374528373",
    "isbn_13": "978-0374528379",
}
from typing import TypedDict
class Book(TypedDict):
    """Typed dictionary structure for a book object."""
    author: str
    title: str
    publication_year: int
    isbn_10: Optional[str]
    isbn_13: Optional[str]
brothers_karamazov: Book = {
    "author": "Fyodor Dostoevsky",
    "title": "The Brothers Karamazov",
    "publication_year": 1880,
    "isbn_10": "0374528373",
    "isbn_13": "978-0374528379",
}
from typing import NamedTuple
class Book(NamedTuple):
    """Container class for a Book and its attributes."""
    author: str
    title: str
    publication_year: int
    isbn_10: Optional[str]
    isbn_13: Optional[str]
brothers_karamazov = Book(
    author="Fyodor Dostoevsky",
    title="The Brothers Karamazov",
    publication_year=1880,
    isbn_10="0374528373",
    isbn_13="978-0374528379",
)
from dataclasses import dataclass
@dataclass
class Book:
    """Container class for a Book and its attributes."""
    author: str
    title: str
    publication_year: int
    isbn_10: Optional[str]
    isbn_13: Optional[str]
brothers_karamazov = Book(
    author="Fyodor Dostoevsky",
    title="The Brothers Karamazov",
    publication_year=1880,
    isbn_10="0374528373",
    isbn_13="978-0374528379",
)