@dataclass
coreintermediate@dataclass reads a class's type-annotated attributes and generates __init__, __repr__, and __eq__ for you. You still write the attribute list; Python writes the boilerplate methods that normally go with it.
Think of it as
A plain class is a blank form you fill in by hand every time — write __init__ to accept the fields, write __repr__ to print them, write __eq__ to compare them. @dataclass reads the field list once and prints all three forms for you, correctly, from that one list.
What we're doing: Confirm @dataclass actually generates a working __init__, __repr__, and __eq__ from three annotated fields, and contrast that with the same class written by hand.
- 4
- @dataclass reads the three annotations below it and builds __init__, __repr__, and __eq__ from them — nothing else in the class body is required.
- 15
- repr(o1) shows every field by name, generated from the annotation order — a plain class would print a memory address instead.
- 16
- o1 == o2 compares field by field and is True, even though they are two separate objects — a plain class compares by identity instead.
Order(order_id='A100', total_cents=2599, is_paid=False)
True
False
<__main__.PlainOrder object at 0x000001A8F3912120>
FalseWhy this works: @dataclass generates __init__, __repr__, and __eq__ once, from the field list, at class-creation time — it does not change what Python objects fundamentally are. PlainOrder, without any of the three defined, falls back to object's defaults: a memory-address repr and identity-based equality, which is why p1 == p2 is False even though every field matches.
Expecting @dataclass to validate types at runtime
Wrong
Better
What you see: No error at construction time — total_cents silently holds a str instead of an int, and the bug surfaces later wherever the code assumes it is a number.
Why: total_cents: int is a type hint, read by a type checker like mypy, not a runtime check. @dataclass only uses the annotation to know a field exists and what order it comes in — it never inspects the value passed in. Real runtime validation needs an explicit check, most often in __post_init__, or a library built for it (see Dataclasses vs Pydantic models).
- Annotated fields — order_id: str, total_cents: int, is_paid: bool = False
- @dataclass reads them — at class-creation time, once
- __init__, __repr__, __eq__ — generated and attached to the class
Remember: @dataclass generates __init__, __repr__, and __eq__ from type-annotated fields — it never validates or enforces those types at runtime.
See also: frozen dataclasses · default values and field · equality dunders

