English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Vous pouvez changer le sens des opérateurs en Python en fonction des opérandes utilisés. Cette pratique est appelée overload d'opérateur.
Python operatorsPour les classes intégrées. Mais le même opérateur a des comportements différents pour différents types. Par exemple,+L'opérateur effectue l'addition arithmétique de deux nombres, fusionne deux listes et relie deux chaînes de caractères.
Cette fonctionnalité en Python permet à un même opérateur d'avoir des significations différentes selon le contexte, ce qui est appelé overload d'opérateur.
Alors, que se passe-t-il lorsque nous les utilisons avec des objets de classes définies par l'utilisateur ? Regardons la classe suivante, qui tente de simuler un point dans un système de coordonnées bidimensionnel.
class Point: def __init__(self, x = 0, y = 0): self.x = x self.y = y
Maintenant, exécutez le code et essayez d'ajouter deux points dans le shell Python.
>>> p1 = Point(2,3) >>> p2 = Point(-1,2) >>> p1 + p2 Traceback (appel le plus récent en dernier): ... TypeError: operandes non prises en charge pour +: 'Point' et 'Point'
Wah ! Il y a beaucoup d'erreurs. Un TypeError est déclenché car Python ne sait pas comment ajouter deux objets Point ensemble.
La bonne nouvelle est que nous pouvons enseigner cela à Python par le biais de l'overloading des opérateurs. Mais d'abord, laissons-nous familiariser avec les fonctions spéciales.
Les fonctions spéciales en Python commencent par deux traits de soulignement __ sont appelées fonctions spéciales. C'est parce qu'elles ne sont pas des fonctions ordinaires. Le fonction __init__() que nous avons définie précédemment en fait partie. Elle est appelée chaque fois que nous créons un nouveau objet de la classe. Python contient de nombreuses fonctions spéciales.
En utilisant les fonctions spéciales, nous pouvons rendre notre classe compatible avec les fonctions intégrées.
>>> p1 = Point(2,3) >>> print(p1) <__main__.Point object at 0x00000000031F8CC0>
La sortie d'impression n'a pas atteint l'effet prévu. Mais si nous définissons la méthode __str__() dans la classe, nous pouvons contrôler la manière dont elle est imprimée. Nous l'ajoutons à notre classe.
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, essayons à nouveau avec la fonction print().
>>> p1 = Point(2,3) >>> print(p1) (2,3)
Il s'avère que c'est mieux, lorsque nous utilisons les fonctions intégrées str() ou format(), elles appellent la même méthode format().
>>> str(p1) '('2,3)' >>> format(p1) '('2,3)'
Ainsi, lorsque vous exécutez str(p1) ou format(p1) lorsque Python exécute p1__str__() est ainsi nommé, fonction spéciale. Continuons avec le surcharge de l'opérateur.
doit être surchargé+Le symbole, nous devons implémenter la fonction __add__() dans la classe. Avec le droit vient aussi une grande responsabilité. Nous pouvons faire n'importe quoi dans cette fonction. Mais il est sage de retourner un objet Point avec la somme des coordonnées.
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): x = self.x + other.x y = self.y + other.y return Point(x, y)
Maintenant, essayons à nouveau.
>>> p1 = Point(2,3) >>> p2 = Point(-1,2) >>> print(p1 + p2) (1,5)
En réalité, lorsque vous exécutez p1 + p2lorsque Python appelle p1 __add__(p2) c'est-à-dire Point.__add__(p1,p2)。 De même, nous pouvons surcharger d'autres opérateurs. La liste des fonctions spéciales à implémenter est la suivante.
opérateur | expression | à l'intérieur |
---|---|---|
Addition (+) | p1 + p2 | p1 __add__(p2) |
Soustraction (-) | p1-p2 | p1 __sub__(p2) |
Multiplication (*) | p1 * p2 | p1 __mul__(p2) |
Puissance (**) | p1 ** p2 | p1 __pow__(p2) |
Division réelle (/) | p1 / p2 | p1 __truediv__(p2) |
Division entière (//) | p1 // p2 | p1 __floordiv__(p2) |
Calcul de la reste (%) | p1%p2 | p1 __mod__(p2) |
Déplacement bit à gauche (<<) | p1 << p2 | p1 __lshift__(p2) |
Déplacement bit à droite (>>) | p1 >> p2 | p1 __rshift__(p)2) |
Bitwise AND (and) | p1 and p2 | p1 .__ and __ (p2) |
Bitwise OR (or) | p1 | 2 | p1 .__ or __ (p2) |
Bitwise XOR (^) | p1 ^ p2 | p1 .__ xor __ (p2) |
Bitwise NOT(~) | ~p1 | p1 .__ invert __ () |
Python does not limit operator overloading to arithmetic operators. We can also overload comparison operators.
Suppose, we want to implement the less than operator (<) in the Point class. Let's compare the sizes of these points from the origin and return the result for this purpose. It can be implemented as follows.
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
Try running these examples in the Python shell.
>> Point(1,1) < Point(-2,-3) True >> Point(1,1) < Point(0.5,-0.2) False >> Point(1,1) < Point(1,1) False
Similarly, the following lists the special functions that we need to implement to overload other comparison operators.
operator | expression | Internal |
---|---|---|
Less than (<) | p1 <p2 | p1 .__ lt __ (p2) |
Less than or equal to (<=) | p1 <= p2 | p1 .__ le __ (p2) |
Equal to (==) | p1 == p2 | p1 .__ eq __ (p2) |
Not equal to (!=) | p1!= p2 | p1 .__ ne __ (p2) |
Greater than (>) | p1> p2 | p1 .__ gt __ (p2) |
Greater than or equal to (>=) | p1>= p2 | p1 .__ ge __ (p2) |