🎓 A1Learner
🔍

Python Dataclasses

A dataclass is a class that mainly holds data.

A plain class repeats itself

A plain class writes each routine method by hand. Most lines just store, show, and compare the same fields.

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Dog(name={self.name!r}, age={self.age})"

    def __eq__(self, other):
        if not isinstance(other, Dog):
            return NotImplemented
        return (self.name, self.age) == (other.name, other.age)

The dataclass version

@dataclass is a decorator: a tool that rewrites the class under it. Two field lines now do the work of the whole class above.

from dataclasses import dataclass

@dataclass
class Dog:
    name: str
    age: int

rex = Dog("Rex", 4)
print(rex)
print(rex == Dog("Rex", 4))

Annotations declare the fields

An annotation is the type written after a name. Each annotated line becomes a field, taken in order.

buddy = Dog("Buddy", 2)
print(buddy.name)
print(buddy.age)

Give a field a default

A field with a default can be left out. Fields with defaults must come after fields without them.

from dataclasses import dataclass

@dataclass
class Dog:
    name: str
    age: int = 1

pup = Dog("Pip")
print(pup)

Turn equality off with eq=False

With eq=False, the decorator writes no __eq__ method. == then checks whether both sides are the same object.

from dataclasses import dataclass

@dataclass(eq=False)
class Dog:
    name: str
    age: int

first = Dog("Rex", 4)
second = Dog("Rex", 4)
print(first == second)
print(first == first)

Example

from dataclasses import dataclass

@dataclass
class Dog:
    name: str
    breed: str
    age: int = 1

rex = Dog("Rex", "Collie", 4)
pip = Dog("Pip", "Pug")
print(rex)
print(pip)
print(rex == Dog("Rex", "Collie", 4))
print(rex.name, rex.age)

Key points

  • Dataclass: a class that mainly holds data, with routine methods generated
  • Use a dataclass when a class mainly stores named fields
  • Use a dict when the keys arrive as outside data and change often
  • Use a plain class when behavior matters more than the data
  • eq=False: keeps the default identity check instead of field equality

In this example, Dog is a dataclass with three fields. name and breed are required, and age defaults to 1. rex passes all three values, so its age is 4. pip leaves age out, so the default 1 appears. The generated __repr__ prints each field with its name. The generated __eq__ compares rex with an equal Dog and returns True.

Note

An annotation does not enforce its type.

Python happily stores a string in an int field.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

What does @dataclass write for your class?