Compare dataclass records by declared fields
Also published in our Blogger archive.
Compare dataclass records by declared fields
Dataclasses generate an equality method by default. For a record such as Ticket, that makes equality useful for checking whether two separately created values represent the same declared state. The example creates two open documentation tickets with the same project, number, and status, then creates a third ticket whose status differs. The assertions establish the expected value comparisons before the program prints the two boolean results.
Generated dataclass equality compares fields in declaration order, and it requires both operands to be instances of the identical type. That is why Ticket("docs", 17, "open") compares equal to another Ticket with the same values, but not to a plain tuple containing similar data. A changed field, such as status, makes these records unequal because it participates in comparison by default.
Equality is only as meaningful as the selected fields and their own equality behavior. For example, a field containing a mutable collection can change after construction, and a domain may need a custom identity rule instead of full-record equality. If a field should not affect equality, configure it explicitly with field(compare=False) rather than relying on a convention. Dataclasses and their generated __eq__ support were introduced in Python 3.7.
The official dataclasses documentation explains the generated equality method and its identical-type requirement.
AI assistance disclosure: This article was drafted with AI assistance and should be reviewed against the domain’s identity rules.
from dataclasses import dataclass
@dataclass
class Ticket:
project: str
number: int
status: str
open_ticket = Ticket("docs", 17, "open")
same_fields = Ticket("docs", 17, "open")
closed_ticket = Ticket("docs", 17, "closed")
assert open_ticket == same_fields
assert open_ticket != closed_ticket
assert open_ticket != ("docs", 17, "open")
print(open_ticket == same_fields, open_ticket == closed_ticket)
True False