Need a class that mainly stores data? Writing the same constructor assignments and string representation for every class gets repetitive. Decorate the class with `@dataclass` to generate methods such as `__init__` and `__repr__` while keeping a custom class you can extend. section 9.2 section 9.2.5
Define a bill
```python from dataclasses import dataclass @dataclass class Bill: table_number: int meal_amount: float served_by: str tip_amount: float = 0 print(Bill(5, 60.5, "John")) # Bill(table_number=5, meal_amount=60.5, served_by='John', tip_amount=0) ``` The annotated names become fields. No explicit constructor or representation method is needed, and the default lets callers omit `tip_amount`. section 9.2.1 section 9.2.2
Annotations matter: `dataclass` uses the class’s `__annotations__` to find fields and generate the applicable methods. Put fields without defaults before fields with defaults, just as you would with function parameters. section 9.2.2
Choose field behavior to fit the data:
- Leave the class mutable when instances need updating. Use `@dataclass(frozen=True)` when changes should be prevented; assigning to a field then raises `FrozenInstanceError`. section 9.2.3
- To extend a data class, decorate the subclass too. Its constructor takes inherited fields before new fields. A defaulted superclass field cannot precede a required subclass field, so avoid superclass defaults when subclasses need that flexibility. section 9.2.4
- For a mutable field such as a list, do not simply copy the ordinary default-value pattern; the `dataclasses.field` function is identified as the tool to investigate for that case. section 9.2.6
Use generated construction after JSON decoding
A task represented as a dictionary can become a `Task` instance through its generated constructor: `Task(**task_dict)`. A class method can wrap that conversion when decoded JSON must become objects with the class’s functionality rather than remain dictionaries. section 9.3.3






