Opérations in-place
Les opérations in-place sont des opérations qui modifient la valeur d'un objet en place, sans créer un nouvel objet. Elles sont désignées par les opérateurs d'affectation augmentée tels que +=
, -=
, *=
, /=
, etc.
Si l'opérateur in-place n'est pas défini pour une classe Python, alors l'opérateur binaire sera utilisé à la place lorsqu'une opération in-place est tentée.
Voici un exemple dans inplace_example1.py
, changez les opérateurs binaires en opérateurs in-place :
from number import MyNumber
## Crée deux nouveaux objets MyNumber
a = MyNumber(5)
b = MyNumber(3)
print(f'{a.value=}, {b.value=}') ## Sortie : a.value=5, b.value=3
a += b
## Utilise la méthode __add__ avec la fonction print
print(f'après a+=b: {a.value=}') ## Sortie : après a+=b: (a+b).value=8
Pour exécuter l'exemple, tapez la commande suivante dans le terminal :
python inplace_example1.py
Le résultat montre que la méthode __add__
a été utilisée lors de l'opération +=
.
Ensuite, nous allons implémenter les opérations in-place dans MyNumber
, et leur comportement avec les opérateurs binaires correspondants sera légèrement différent.
__iadd__
La méthode magique __iadd__
définit comment doit se comporter l'opération d'addition in-place. Lorsque vous utilisez l'opérateur +=
sur des instances de votre classe, cette méthode est appelée.
#... (code précédent dans number.py)
def __iadd__(self, other: 'MyNumber') -> 'MyNumber':
"""Ajoute la valeur de l'autre instance à la valeur de l'instance en place."""
print(f'entrée : {self.value=}, {other.value=}')
self.value += other.value
print(f'après += : {self.value=}')
return self
__isub__
La méthode magique __isub__
définit comment doit se comporter l'opération de soustraction in-place. Lorsque vous utilisez l'opérateur -=
sur des instances de votre classe, cette méthode est appelée.
#... (code précédent dans number.py)
def __isub__(self, other: 'MyNumber') -> 'MyNumber':
"""Soustrait la valeur de l'autre instance de la valeur de l'instance en place."""
print(f'entrée : {self.value=}, {other.value=}')
self.value -= other.value
print(f'après -= : {self.value=}')
return self
__imul__
La méthode magique __imul__
définit comment doit se comporter l'opération de multiplication in-place. Lorsque vous utilisez l'opérateur *=
sur des instances de votre classe, cette méthode est appelée.
#... (code précédent dans number.py)
def __imul__(self, other: 'MyNumber') -> 'MyNumber':
"""Multiplie la valeur de l'instance par la valeur de l'autre instance en place."""
print(f'entrée : {self.value=}, {other.value=}')
self.value *= other.value
print(f'après *= : {self.value=}')
return self
__itruediv__
La méthode magique __itruediv__
définit comment doit se comporter l'opération de division réelle in-place. Lorsque vous utilisez l'opérateur /=
sur des instances de votre classe, cette méthode est appelée.
#... (code précédent dans number.py)
def __itruediv__(self, other: 'MyNumber') -> 'MyNumber':
"""Divise la valeur de l'instance par la valeur de l'autre instance en place."""
print(f'entrée : {self.value=}, {other.value=}')
self.value /= other.value
print(f'après /= : {self.value=}')
return self
__ifloordiv__
La méthode magique __ifloordiv__
définit comment doit se comporter l'opération de division entière in-place. Lorsque vous utilisez l'opérateur //=
sur des instances de votre classe, cette méthode est appelée.
#... (code précédent dans number.py)
def __ifloordiv__(self, other: 'MyNumber') -> 'MyNumber':
"""Effectue une division entière en place de la valeur de l'instance par la valeur de l'autre instance."""
print(f'entrée : {self.value=}, {other.value=}')
self.value //= other.value
print(f'après //= : {self.value=}')
return self
__imod__
La méthode magique __imod__
définit comment doit se comporter l'opération de modulo in-place. Lorsque vous utilisez l'opérateur %=
sur des instances de votre classe, cette méthode est appelée.
#... (code précédent dans number.py)
def __imod__(self, other: 'MyNumber') -> 'MyNumber':
"""Effectue une opération de modulo en place de la valeur de l'instance par la valeur de l'autre instance."""
print(f'entrée : {self.value=}, {other.value=}')
self.value %= other.value
print(f'après %= : {self.value=}')
return self
__ipow__
La méthode magique __ipow__
définit comment doit se comporter l'opération de puissance in-place. Lorsque vous utilisez l'opérateur **=
sur des instances de votre classe, cette méthode est appelée.
#... (code précédent dans number.py)
def __ipow__(self, other: 'MyNumber') -> 'MyNumber':
"""Élève la valeur de l'instance à la puissance de la valeur de l'autre instance en place."""
print(f'entrée : {self.value=}, {other.value=}')
self.value **= other.value
print(f'après **= : {self.value=}')
return self
Exemple : Utilisation des opérations in-place
Maintenant que nous avons défini les opérateurs in-place pour notre classe MyNumber
, voyons comment ils fonctionnent dans inplace_example2.py
:
from number import MyNumber
## Crée un nouvel objet MyNumber
a = MyNumber(13)
## Utilise la méthode __iadd__
a += MyNumber(5)
## Sortie :
## entrée : self.value=13, other.value=5
## après += : self.value=18
## Utilise la méthode __isub__
a -= MyNumber(5)
## Sortie :
## entrée : self.value=18, other.value=5
## après -= : self.value=13
## Utilise la méthode __imul__
a *= MyNumber(5)
## Sortie :
## entrée : self.value=13, other.value=5
## après *= : self.value=65
## Utilise la méthode __itruediv__
a /= MyNumber(5)
## Sortie :
## entrée : self.value=65, other.value=5
## après /= : self.value=13.0
## Utilise la méthode __ifloordiv__
a //= MyNumber(2)
## Sortie :
## entrée : self.value=13.0, other.value=2
## après //= : self.value=6.0
## Utilise la méthode __imod__
a %= MyNumber(4)
## Sortie :
## entrée : self.value=6.0, other.value=4
## après %= : self.value=2.0
## Utilise la méthode __ipow__
a **= MyNumber(3)
## Sortie :
## entrée : self.value=2.0, other.value=3
## après **= : self.value=8.0
Ensuite, tapez la commande suivante dans le terminal pour exécuter le script.
python inplace_example2.py