Equality, hashing and ordering
Without help, == on your objects compares identity. Define __eq__ to compare values. For a type you do not handle, return NotImplemented: Python then tries the other operand's method, and for == finally falls back to identity.
from functools import total_ordering
@total_ordering
class Money:
def __init__(self, cents):
self.cents = cents
def __eq__(self, other):
if not isinstance(other, Money):
return NotImplemented
return self.cents == other.cents
def __lt__(self, other):
if not isinstance(other, Money):
return NotImplemented
return self.cents < other.cents
def __hash__(self):
return hash(self.cents)
print(Money(5) == Money(5))
print(Money(5) > Money(2))
print(len({Money(5), Money(5)}))Hash follows equality
Sets and dicts find a key by its hash, then confirm with ==. Equal objects must have equal hashes. Defining __eq__ sets __hash__ to None, so instances become unhashable until you write one. Hash the same fields you compare, and only fields that never change.
Ordering
sorted, min and max need only <. @total_ordering from functools derives <=, > and >= from __eq__ and __lt__.
Your task
Write Version(text) storing text and parts, the tuple of ints from a string like "1.10.2". Versions compare by parts with all six comparison operators, work as set members and dict keys, return NotImplemented against other types, and repr as Version('1.10.2').
The explanation opens here once every check passes.