Elegant ways to support equivalence equality in Python classes
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Supporting equality in Python classes is mostly about deciding what "same value" means for your domain and then implementing that rule consistently. The elegant solution is usually the smallest one that gets __eq__, hashing, and type behavior correct without surprising people who use the class.
Core Sections
What == should mean for your class
By default, user-defined objects compare by identity, not by value. Two different instances are considered unequal even if their fields match.
If your class represents a value object, such as a point, money amount, or date range, overriding __eq__ is appropriate.
A correct manual __eq__
The important detail is returning NotImplemented when the other object is not of a compatible type. That lets Python try reflected comparison or fall back cleanly.
Do not return False immediately for unrelated types unless that is truly what you want. NotImplemented is the more correct protocol-level answer.
Keep __hash__ aligned with equality
If two objects compare equal, they must produce the same hash when used in sets or as dictionary keys. If you override __eq__ on a mutable class and do nothing else, Python may make the class unhashable to protect you from subtle bugs.
For immutable value objects, implement both:
If the object is mutable, it is often safer to avoid hashing entirely.
dataclass is the cleanest option most of the time
For straightforward value objects, dataclasses.dataclass is usually the most elegant solution because it generates __eq__ for you and can also generate a safe hash policy.
frozen=True is a strong default for value objects because it makes the equality contract easier to trust.
Equality across related classes
Be explicit about subclass behavior. Sometimes isinstance(other, BaseClass) is correct. Sometimes equality should require the exact same type so that subclasses do not accidentally compare equal while carrying different semantics.
This stricter check avoids odd cases where two different subclasses happen to share the same data shape but should not be interchangeable.
Keep equality small and predictable
A good equality implementation should:
- compare only the fields that define logical identity
- avoid side effects
- avoid expensive external lookups
- stay consistent over the lifetime of the object
If equality depends on database state, timestamps, or mutable caches, code becomes hard to reason about quickly.
Common Pitfalls
- Returning
Falseinstead ofNotImplementedfor incompatible types and breaking Python's comparison protocol. - Defining
__eq__without thinking about__hash__, then getting confusing behavior in sets or dictionaries. - Using mutable fields in a hash calculation and making key lookups unstable.
- Comparing too many incidental fields instead of only the values that define real equivalence.
- Letting subclass instances compare equal to base-class instances when their semantics are not actually the same.
Summary
- Value-based equality in Python starts with a correct
__eq__implementation. - Return
NotImplementedfor unsupported types so Python can handle comparisons properly. - Keep hashing consistent with equality, or leave mutable objects unhashable.
- Prefer
@dataclass(frozen=True)for simple immutable value objects. - Define equality in terms of domain meaning, not merely whatever fields happen to exist.
Related reading
- Element-wise addition of 2 lists?
- elif in list comprehension conditionals
- Else clause on Python while statement
- Emacs bulk indent for Python
- Encrypt and decrypt using PyCrypto AES-256
- Ensemble of different kinds of regressors using scikit-learn or any other python framework
- EOFError Compressed file ended before the end-of-stream marker was reached - MNIST data set
- e.printStackTrace equivalent in python
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.