En Python, les classes personnalisées peuvent implémenter les méthodes __eq__ et __ne__ pour définir l'équivalence pour les opérateurs == et !=, respectivement. Bien que la méthode traditionnelle de comparaison des attributs du dictionnaire soit simple, elle présente certaines limites.
Considérez le scénario suivant :
class Number: def __init__(self, number): self.number = number n1 = Number(1) n2 = Number(1) # Default comparison fails: they are different objects assert n1 != n2
Pour résoudre ce problème , nous pouvons remplacer la méthode __eq__ :
class Number: def __init__(self, number): self.number = number def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return False
Cependant, pour Python 2, nous devons également implémenter __ne__ pour garantir un comportement commutatif :
class Number: def __init__(self, number): self.number = number def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return False def __ne__(self, other): return not self.__eq__(other)
Cela garantit que n1 == n2 est évalué à True, comme prévu.
L'introduction de sous-classes complique la comparaison d'équivalence :
class SubNumber(Number): pass n3 = SubNumber(1) # Subclass comparison fails for classic-style classes assert n1 == n3 # False (for classic-style classes) assert n3 == n1 # True # Non-commutative comparison assert n1 != n3 # True (for classic-style classes) assert n3 != n1 # False
Pour les classes de style classique, la méthode de comparaison est invoquée en fonction de la type du premier opérande, conduisant à un comportement non commutatif. Pour résoudre ce problème, nous pouvons renvoyer NotImplemented pour les types d'opérandes non pris en charge, ce qui délègue la comparaison à la méthode de l'autre opérande :
def __eq__(self, other): if isinstance(other, Number): return self.number == other.number return NotImplemented
Enfin, notez que les ensembles utilisent des identifiants d'objet pour hachage, ce qui peut conduire à des résultats incorrects :
assert len(set([n1, n2, n3])) == 3 # Incorrectly reports 3 unique numbers
Pour résoudre ce problème, nous pouvons remplacer la méthode __hash__ :
def __hash__(self): return hash(tuple(sorted(self.__dict__.items())))
Avec ces améliorations, les comportements d'équivalence et d'unicité deviennent corrects et cohérent, garantissant des comparaisons robustes et une représentation précise dans les ensembles :
assert len(set([n1, n2, n3])) == 1 assert len(set([n1, n2, n3, n4])) == 2
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!