Home > Article > Backend Development > How to Achieve Equivalence in Python Classes: A Deep Dive into __eq__, __ne__, and Hashing?
In Python, custom classes can be equipped with equivalence through the implementation of the special methods eq and ne for the == and != operators, respectively. This enables objects from such classes to be compared for equality based on their attributes.
A simple yet effective method to achieve equivalence is by comparing the dictionaries containing the attributes of the objects:
class Foo: def __init__(self, item): self.item = item def __eq__(self, other): if isinstance(other, self.__class__): return self.__dict__ == other.__dict__ else: return False def __ne__(self, other): return not self.__eq__(other)
While this method establishes equivalence between objects of the same class, it faces challenges when dealing with subclasses or instances of unrelated types. To address these issues, the following considerations are important:
Non-commutativity of Classic-style Classes:
Classic-style Python 2 classes execute the eq method of the first operand while ne is called on the second. To ensure symmetry, consider returning NotImplemented for unsupported operand types.
Returning NotImplemented for Non-supported Types:
For cases where the operand is of a different type (no inheritance), returning NotImplemented in eq and ne delegates the comparison to the reflected method of the other operand. This ensures commutativity and allows for the use of sets to determine unique instances.
Hashing and Set Handling:
By default, objects are hashed using their object identifier. To ensure proper comparison within sets, override hash to calculate a consistent hash based on the object's attributes.
Incorporating these considerations results in a more robust implementation for object equivalence:
class Number: def __init__(self, number): self.number = number def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return NotImplemented def __ne__(self, other): x = self.__eq__(other) if x is not NotImplemented: return not x return NotImplemented def __hash__(self): return hash(tuple(sorted(self.__dict__.items())))
This implementation ensures correct equivalence and hashing even across subclasses and unrelated instances, providing a more elegant and comprehensive means of supporting equivalence in Python classes.
The above is the detailed content of How to Achieve Equivalence in Python Classes: A Deep Dive into __eq__, __ne__, and Hashing?. For more information, please follow other related articles on the PHP Chinese website!