Dataclasses
Data-holding classes without the boilerplate.
4 minute read
Big idea
A dataclass is a class mostly for holding data. Add @dataclass above it, list the fields with their types, and Python writes __init__, __repr__, and __eq__ for you.
Before and after
A plain class for a book needs a lot of typing:
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
The dataclass version says the same thing — and more:
from dataclasses import dataclass
@dataclass
class Book:
title: str
author: str
pages: int
b = Book("Dune", "Frank Herbert", 412)
print(b)
print(b.pages)
print(b == Book("Dune", "Frank Herbert", 412))output
Book(title='Dune', author='Frank Herbert', pages=412)
412
TrueRun and edit it in the app.
title: str— a field with a type hint. The hint documents the type; Python doesn't enforce it.- You get a readable
printand==that compares field by field — for free.
Defaults and methods
Fields can have defaults (after the ones without), and a dataclass is still a class — add methods as usual:
from dataclasses import dataclass
@dataclass
class Item:
name: str
price: float
quantity: int = 1
def total(self):
return self.price * self.quantity
cart = [Item("pen", 1.5, 4), Item("book", 12.0)]
for item in cart:
print(item.name, item.total())
print(sum(item.total() for item in cart))What does it print? Show the answer
pen 6.0
book 12.0
18.0Run and edit it in the app.
A list default needs a factory
As with function defaults, a list default would be shared between objects. Dataclasses refuse it outright, and give you field(default_factory=list) instead:
from dataclasses import dataclass
@dataclass
class Team:
name: str
members: list = []
t = Team("Blue")
t.members.append("Ada")
print(t)output
Team(name='Blue', members=['Ada'])Run and edit it in the app.
The error is ValueError: mutable default <class 'list'> for field members is not allowed. Import field too, and write members: list = field(default_factory=list) — a fresh empty list for every team.
Sorting dataclasses
order=True adds <, > and friends, comparing fields in order — so a list of them can be sorted directly. More often you'll sort with a key:
books.sort(key=lambda b: b.pages)
Which methods does @dataclass write for you by default?
Watch it
Think of it like
A form with labelled boxes. You design the form once — Name, Price, Quantity — and every copy you fill in prints neatly and can be compared box by box.
Key terms
- Dataclass — A class whose
__init__,__repr__, and__eq__are generated from its fields. - Field — One named piece of data in a dataclass.
- Type hint —
name: str; documents the expected type.
Check yourself
What does @dataclass generate?
Does a type hint like pages: int stop you storing a string?
How do you give a dataclass field an empty-list default?