Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Python

Maîtriser la surcharge d'opérateurs en Python : guide pratique

Surcharge d'opérateurs Python

Découvrez comment redéfinir le comportement des opérateurs en Python en utilisant des méthodes spéciales comme __add__, __lt__, et plus, améliorant vos conceptions POO.

Surcharge d'opérateurs Python

Les opérateurs intégrés de Python fonctionnent différemment selon les types d'opérandes. L'opérateur +, par exemple, additionne des nombres, concatène des chaînes ou fusionne des listes. Cette flexibilité est réalisée grâce à la surcharge d'opérateurs — une fonctionnalité qui vous permet d'attribuer des significations contextuelles aux opérateurs pour vos propres classes.

Considérez une simple classe Point qui représente une coordonnée dans un plan 2D. Sans méthodes spéciales, tenter d'additionner deux points lèvera une TypeError :

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
p1 = Point(1, 2)
p2 = Point(2, 3)
print(p1+p2)

Sortie

Traceback (most recent call last): File "<string>", line 9, in <module> print(p1+p2) TypeError: unsupported operand type(s) for +: 'Point' and 'Point'

Comme Python n'a pas de connaissance intégrée de comment combiner deux instances Point, il lève une exception. La surcharge d'opérateurs nous permet de définir ce comportement nous-mêmes.


Méthodes spéciales Python

Les méthodes entourées de doubles underscores — __init__, __str__, __add__, etc. — sont connues sous le nom de méthodes spéciales ou méthodes « dunder ». Elles sont invoquées implicitement par l'exécution de Python et sont les points d'ancrage pour la surcharge d'opérateurs, les protocoles de conteneurs, et plus.

Par exemple, la méthode __str__ contrôle comment un objet est converti en chaîne lisible par l'humain. Par défaut, afficher un objet montre son adresse mémoire, ce qui n'est souvent pas utile. Redéfinir __str__ peut rendre le débogage et la journalisation bien plus clairs :

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
    def __str__(self):
        return '({0}, {1})'.format(self.x, self.y)

Maintenant, quand nous affichons un Point, nous obtenons :

p1 = Point(2, 3)
print(p1)

Sortie

(2, 3)

La même représentation est utilisée par str(p1) et format(p1) car Python appelle internement p1.__str__().


Surcharge de l'opérateur +

Pour personnaliser l'addition pour les objets Point, implémentez __add__ :

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
    def __str__(self):
        return '({0}, {1})'.format(self.x, self.y)
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

Test du nouveau comportement :

p1 = Point(1, 2)
p2 = Point(2, 3)
print(p1 + p2)

Sortie

(3, 5)

Sous le capot, Python exécute p1.__add__(p2), qui retourne un nouveau Point avec les coordonnées additionnées.

Voici une référence rapide pour les autres opérateurs arithmétiques et les méthodes spéciales à implémenter :

OpérateurExpressionMéthode spéciale
Additionp1 + p2__add__(self, other)
Soustractionp1 - p2__sub__(self, other)
Multiplicationp1 * p2__mul__(self, other)
Puissancep1 ** p2__pow__(self, other)
Divisionp1 / p2__truediv__(self, other)
Division entièrep1 // p2__floordiv__(self, other)
Modulop1 % p2__mod__(self, other)
Décalage gauchep1 << p2__lshift__(self, other)
Décalage droitp1 >> p2__rshift__(self, other)
ET bit à bitp1 & p2__and__(self, other)
OU bit à bitp1 | p2__or__(self, other)
OU exclusif bit à bitp1 ^ p2__xor__(self, other)
NON bit à bit~p1__invert__(self)

Surcharge des opérateurs de comparaison

La surcharge d'opérateurs n'est pas limitée à l'arithmétique. Les opérateurs de comparaison peuvent aussi être adaptés. Par exemple, pour comparer des points basés sur leur distance à l'origine, redéfinissez __lt__ :

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
    def __str__(self):
        return '({0}, {1})'.format(self.x, self.y)
    def __lt__(self, other):
        self_mag = self.x**2 + self.y**2
        other_mag = other.x**2 + other.y**2
        return self_mag < other_mag

Utilisation :

p1 = Point(1, 1)
p2 = Point(-2, -3)
p3 = Point(1, -1)
print(p1 < p2)  # True
print(p2 < p3)  # False
print(p1 < p3)  # False

Les autres méthodes de comparaison suivent un motif similaire :

OpérateurExpressionMéthode spéciale
Inférieur àp1 < p2__lt__(self, other)
Inférieur ou égal àp1 <= p2__le__(self, other)
Égal àp1 == p2__eq__(self, other)
Différent dep1 != p2__ne__(self, other)
Supérieur àp1 > p2__gt__(self, other)
Supérieur ou égal àp1 >= p2__ge__(self, other)

En définissant soigneusement ces méthodes, vous pouvez faire participer des objets personnalisés naturellement dans des contextes arithmétiques et de comparaison, améliorant ainsi la lisibilité et la maintenabilité du code.

Python

  1. Maîtriser les types de données Python : Guide pratique
  2. Maîtriser les opérateurs Python : Guide complet
  3. Maîtriser l'instruction pass en Python : Guide pratique
  4. Maîtriser les arguments de fonctions Python : Positionnels, nommés et paramètres par défaut
  5. Maîtriser les dictionnaires Python : création, manipulation et techniques avancées
  6. Maîtriser l'héritage Python : concepts, syntaxe et exemples pratiques
  7. Maîtriser les itérateurs Python : fonctionnement et création des vôtres
  8. Les fermetures Python expliquées : comment les fonctions imbriquées capturent les variables
  9. Maîtriser le décorateur @property de Python : getters et setters propres et compatibles