Operaciones In-place
Las operaciones in-place son operaciones que modifican el valor de un objeto en el lugar, sin crear un nuevo objeto. Se denotan por los operadores de asignación aumentada, como +=
, -=
, *=
, /=
, etc.
Si el operador in-place no está definido para una clase de Python, entonces se usará el operador binario en su lugar cuando se intente una operación in-place.
Hay un ejemplo en inplace_example1.py
, cambie los operadores binarios a operadores in-place:
from number import MyNumber
## Crea dos nuevos objetos MyNumber
a = MyNumber(5)
b = MyNumber(3)
print(f'{a.value=}, {b.value=}') ## Salida: a.value=5, b.value=3
a += b
## Usa el método __add__ con la función print
print(f'despues de a+=b: {a.value=}') ## Salida:después de a+=b: (a+b).value=8
Para ejecutar el ejemplo, escriba el siguiente comando en la terminal:
python inplace_example1.py
El resultado muestra que se usó el __add__
cuando se intentó la operación +=
.
Luego implementaremos las operaciones in-place en MyNumber
, y su comportamiento con los operadores binarios correspondientes será ligeramente diferente.
__iadd__
El método mágico __iadd__
define cómo debe comportarse la operación de adición in-place. Cuando se utiliza el operador +=
en instancias de su clase, este método se llama.
#... (código anterior en number.py)
def __iadd__(self, other: 'MyNumber') -> 'MyNumber':
"""Agrega el valor de la otra instancia al valor de la instancia in-place."""
print(f'entrada: {self.value=}, {other.value=}')
self.value += other.value
print(f'despues de +=: {self.value=}')
return self
__isub__
El método mágico __isub__
define cómo debe comportarse la operación de sustracción in-place. Cuando se utiliza el operador -=
en instancias de su clase, este método se llama.
#... (código anterior en number.py)
def __isub__(self, other: 'MyNumber') -> 'MyNumber':
"""Resta el valor de la otra instancia al valor de la instancia in-place."""
print(f'entrada: {self.value=}, {other.value=}')
self.value -= other.value
print(f'despues de -=: {self.value=}')
return self
__imul__
El método mágico __imul__
define cómo debe comportarse la operación de multiplicación in-place. Cuando se utiliza el operador *=
en instancias de su clase, este método se llama.
#... (código anterior en number.py)
def __imul__(self, other: 'MyNumber') -> 'MyNumber':
"""Multiplica el valor de la instancia por el valor de la otra instancia in-place."""
print(f'entrada: {self.value=}, {other.value=}')
self.value *= other.value
print(f'despues de *=: {self.value=}')
return self
__itruediv__
El método mágico __itruediv__
define cómo debe comportarse la operación de división real in-place. Cuando se utiliza el operador /=
en instancias de su clase, este método se llama.
#... (código anterior en number.py)
def __itruediv__(self, other: 'MyNumber') -> 'MyNumber':
"""Divide el valor de la instancia por el valor de la otra instancia in-place."""
print(f'entrada: {self.value=}, {other.value=}')
self.value /= other.value
print(f'despues de /=: {self.value=}')
return self
__ifloordiv__
El método mágico __ifloordiv__
define cómo debe comportarse la operación de división entera in-place. Cuando se utiliza el operador //=
en instancias de su clase, este método se llama.
#... (código anterior en number.py)
def __ifloordiv__(self, other: 'MyNumber') -> 'MyNumber':
"""Realiza una división entera in-place del valor de la instancia por el valor de la otra instancia."""
print(f'entrada: {self.value=}, {other.value=}')
self.value //= other.value
print(f'despues de //=: {self.value=}')
return self
__imod__
El método mágico __imod__
define cómo debe comportarse la operación de módulo in-place. Cuando se utiliza el operador %=
en instancias de su clase, este método se llama.
#... (código anterior en number.py)
def __imod__(self, other: 'MyNumber') -> 'MyNumber':
"""Realiza una operación de módulo in-place del valor de la instancia por el valor de la otra instancia."""
print(f'entrada: {self.value=}, {other.value=}')
self.value %= other.value
print(f'despues de %=: {self.value=}')
return self
__ipow__
El método mágico __ipow__
define cómo debe comportarse la operación de potencia in-place. Cuando se utiliza el operador **=
en instancias de su clase, este método se llama.
#... (código anterior en number.py)
def __ipow__(self, other: 'MyNumber') -> 'MyNumber':
"""Eleva el valor de la instancia a la potencia del valor de la otra instancia in-place."""
print(f'entrada: {self.value=}, {other.value=}')
self.value **= other.value
print(f'despues de **=: {self.value=}')
return self
Ejemplo: Usando las Operaciones In-place
Ahora que hemos definido los operadores in-place para nuestra clase MyNumber
, veamos cómo funcionan en inplace_example2.py
:
from number import MyNumber
## Crea un nuevo objeto MyNumber
a = MyNumber(13)
## Usa el método __iadd__
a += MyNumber(5)
## Salida:
## entrada: self.value=13, other.value=5
## después de +=: self.value=18
## Usa el método __isub__
a -= MyNumber(5)
## Salida:
## entrada: self.value=18, other.value=5
## después de -=: self.value=13
## Usa el método __imul__
a *= MyNumber(5)
## Salida:
## entrada: self.value=13, other.value=5
## después de *=: self.value=65
## Usa el método __itruediv__
a /= MyNumber(5)
## Salida:
## entrada: self.value=65, other.value=5
## después de /=: self.value=13.0
## Usa el método __ifloordiv__
a //= MyNumber(2)
## Salida:
## entrada: self.value=13.0, other.value=2
## después de //=: self.value=6.0
## Usa el método __imod__
a %= MyNumber(4)
## Salida:
## entrada: self.value=6.0, other.value=4
## después de %=: self.value=2.0
## Usa el método __ipow__
a **= MyNumber(3)
## Salida:
## entrada: self.value=2.0, other.value=3
## después de **=: self.value=8.0
Luego escriba el siguiente comando en la terminal para ejecutar el script.
python inplace_example2.py