Create a total ordering from equality and one comparison

A small value object often needs more than == and <: callers may also use !=, <=, >, and >=. @functools.total_ordering fills in the missing rich comparison methods when the class supplies __eq__() and one ordering method. Priority implements equality and __lt__() from its integer value, so the decorator can derive >= for the second assertion.

Both implemented methods return NotImplemented for a value that is not a Priority. That gives Python a chance to try the other operand's reflected method; if neither operand can order the pair, an ordering operation raises TypeError. Returning False there would incorrectly state that unlike types are comparable. Equality has different fallback behavior, so Priority(1) == 1 ultimately evaluates to False.

The printed list comes from sorted(), which uses the supplied less-than operation. This pattern is appropriate only when value does not change while an instance is being compared; mutating it can make ordering results inconsistent. total_ordering also adds method calls and more involved tracebacks, so a proven comparison hot spot may justify implementing every rich comparison directly.

AI assistance contributed to this Batu Lab Notes article.

from functools import total_ordering


@total_ordering
class Priority:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        if not isinstance(other, Priority):
            return NotImplemented
        return self.value == other.value

    def __lt__(self, other):
        if not isinstance(other, Priority):
            return NotImplemented
        return self.value < other.value


low = Priority(1)
high = Priority(3)
same_as_high = Priority(3)
assert low < high
assert high >= same_as_high
assert low != high
print(f"low < high: {low < high}")
print(f"high >= same: {high >= same_as_high}")
print([item.value for item in sorted([high, low, Priority(2)])])

Expected stdout:

low < high: True
high >= same: True
[1, 2, 3]

Sources

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic