Value objects need sensible equality and ordering to be used in tests, sets and sorted collections.
The generated __eq__ compares two instances as tuples of their fields, in definition order, and only if they are of exactly the same class. Comparing with any other type returns NotImplemented, so Point(1, 2) == (1, 2) is False.
@dataclass(order=True) additionally generates __lt__, __le__, __gt__ and __ge__, again comparing field tuples: the first field decides, ties fall through to the next field, like sorting tuples. That makes instances usable with sorted(), min(), max() and heapq.
Because comparison follows field order, declare fields in the order you want to sort by, or exclude fields from comparison with field(compare=False) (for example, a cache or a description). A common trick for priority queues is a first field sort_index set in __post_init__.
Notes:
- Ordering between different dataclass types raises
TypeError. eq=Falsekeeps identity-based equality fromobject, useful for entities whose identity matters more than their values.- If you define
__lt__yourself and passorder=True, you get aTypeError; define your own or let the decorator do it, not both. - For ordering by one key only,
functools.total_orderingor akey=function insortedmay be clearer.
Example
from dataclasses import dataclass, field
@dataclass(order=True)
class Version:
major: int
minor: int
patch: int = 0
label: str = field(default="", compare=False) # ignored in == and <
versions = [Version(1, 10), Version(1, 2, 5), Version(0, 9, label="beta")]
print(sorted(versions))
# [Version(major=0, minor=9, patch=0, label='beta'), Version(major=1, minor=2, ...), Version(major=1, minor=10, ...)]
print(Version(2, 0) > Version(1, 99)) # True
print(Version(1, 0, label="a") == Version(1, 0)) # True: label not compared
print(Version(1, 0) == (1, 0, 0)) # False: different typeRemember
- __eq__ compares field tuples of the same class
- order=True adds <, <=, >, >= using field order
- field(compare=False) excludes a field from comparisons
Watch out for
- Declaring fields in an order that doesn't match how instances should sort.