@dataclass
A decorator that generates __init__, __repr__, and __eq__ for a data-storing class, based on type-annotated fields.
- Returns
- The same class, with the generated methods added.
Example
#from dataclasses import dataclass, field
@dataclass
class Student:
name: str
world: int
points: int = 0
badges: list[str] = field(default_factory=list)
emma = Student("Emma", 7)
emma.points += 40
emma.badges.append("Start")
print(emma)
print(emma == Student("Emma", 7, 40, ["Start"]))
print(Student("Jack", 2))Definition and usage
#The @dataclass decorator from the dataclasses module removes repetitive code from classes that store data. You just list the fields with type annotations (name: str), and the decorator generates __init__ with parameters in the same order, a readable __repr__, and __eq__, which compares objects field by field.
Fields can have default values (points: int = 0), but fields without a default must come before them. You give a list, dictionary, or other mutable object as a default value through field(default_factory=list), so that every object gets its own copy. Put any extra steps after object creation, such as validation or computing a helper field, in the __post_init__ method.
The decorator’s parameters change the class’s behavior, for example frozen=True blocks changes to fields, and order=True adds < and > comparisons. The asdict() function turns an object into a dictionary, for example to save as JSON, and replace() creates a copy with some fields changed. Type annotations are not checked while the program runs; they serve editors and tools like mypy.
Syntax
#from dataclasses import dataclass, field
@dataclass
class Name:
field_name: Type
field_with_default: Type = value
items: list[Type] = field(default_factory=list)
@dataclass(frozen=True, order=True)
class Other:
...Parameters
#frozen
bool, default False
WhenTrue, changing a field raisesFrozenInstanceError, and objects can be dictionary keys and set elements.order
bool, default False
Adds the<,<=,>, and>=operators, which compare fields in order, just like tuples.slots
bool, default False
Creates the class with__slots__: objects use less memory, and assigning to a nonexistent field raises an error.kw_only
bool, default False
Forces every field to be given by name when creating the object.
More examples
#from dataclasses import dataclass, field
@dataclass(frozen=True, order=True)
class Result:
points: int
name: str = field(compare=False)
results = [Result(78, "Jack"), Result(92, "Emma"), Result(85, "Mia")]
print([r.name for r in sorted(results, reverse=True)])
best = max(results)
try:
best.points = 100
except AttributeError as error:
print(type(error).__name__, error)field(compare=False) excludes the field from comparisons, so the results are sorted only by points.
from dataclasses import dataclass, field
@dataclass
class Exercise:
number: str
exp: int
world: int = field(init=False)
def __post_init__(self):
if self.exp < 0:
raise ValueError("EXP cannot be negative")
self.world = int(self.number.split("_")[0])
task = Exercise("7_3", 15)
print(task.world)
print(task)import json
from dataclasses import asdict, dataclass, replace
@dataclass
class Course:
title: str
modules: int
premium: bool = False
python = Course("Python", 12)
advanced = replace(python, title="Advanced Python", premium=True)
print(advanced)
print(asdict(python))
print(json.dumps(asdict(advanced), ensure_ascii=False))Good practices
#- Create fields with mutable default values through
field(default_factory=list). Writingbadges: list = []raisesValueErroras soon as the class is defined. - Types in annotations are not checked, so
Student(name=123, world="seven")creates an object without an error. For validation, use__post_init__or the pydantic library. - Objects with
frozen=Truecan be safely shared between parts of the program, because no one can change them by accident.
Related entries
#- namedtuple vs dataclassnamedtuple creates an immutable, lightweight tuple with named fields, while @dataclass creates an ordinary, mutable class with a generated __init__, __repr__, and __eq__.
- classDefines a class: a template for objects that combines data with the functions that act on it.
- __init__()A method called automatically when an object is created. It stores the object’s initial data, its attributes.
- __str__() and __repr__()Methods that define an object’s text appearance: readable for the user (__str__) and technical for the programmer (__repr__).
- Special methodsMethods with double underscores that let objects work with the ==, <, + and in operators, and with the len() function.
Spotted a mistake or missing an example? Write to us.