Maison > développement back-end > Tutoriel Python > Comment garantir des comparaisons d'équivalence cohérentes et robustes pour les classes Python personnalisées, en particulier lorsqu'il s'agit de sous-classes et d'ensembles ?

Comment garantir des comparaisons d'équivalence cohérentes et robustes pour les classes Python personnalisées, en particulier lorsqu'il s'agit de sous-classes et d'ensembles ?

Linda Hamilton
Libérer: 2024-11-09 04:50:02
original
435 Les gens l'ont consulté

How do you ensure consistent and robust equivalence comparisons for custom Python classes, especially when dealing with subclasses and sets?

Approches élégantes pour la comparaison d'équivalence dans les classes Python

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.

Une approche plus raffinée

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
Copier après la connexion

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
Copier après la connexion

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)
Copier après la connexion

Cela garantit que n1 == n2 est évalué à True, comme prévu.

Équivalence des sous-classes

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
Copier après la connexion

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
Copier après la connexion

Hashing et Sets

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
Copier après la connexion

Pour résoudre ce problème, nous pouvons remplacer la méthode __hash__ :

def __hash__(self):
    return hash(tuple(sorted(self.__dict__.items())))
Copier après la connexion

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
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal