Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> python

Dominando la Sobrecarga de Operadores en Python: Guía Práctica

Sobrecarga de Operadores en Python

Descubre cómo redefinir el comportamiento de operadores en Python usando métodos especiales como __add__, __lt__ y más, mejorando tus diseños OOP.

Sobrecarga de Operadores en Python

Los operadores integrados de Python funcionan diferente según los tipos de operandos. El operador +, por ejemplo, suma números, concatena cadenas o fusiona listas. Esta flexibilidad se logra mediante sobrecarga de operadores —una característica que permite asignar significados contextuales a operadores para tus propias clases.

Considera una clase simple Punto que representa una coordenada en un plano 2-D. Sin métodos especiales, intentar sumar dos puntos lanzará TypeError:

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

Salida

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

Como Python no tiene conocimiento integrado de cómo combinar dos instancias Punto, lanza una excepción. La sobrecarga de operadores nos permite definir ese comportamiento nosotros mismos.


Métodos Especiales de Python

Métodos rodeados por doble guion bajo —__init__, __str__, __add__, etc.— son conocidos como métodos especiales o métodos "dunder". Se invocan implícitamente por el runtime de Python y son los puntos de enganche para sobrecarga de operadores, protocolos de contenedores y más.

Por ejemplo, el método __str__ controla cómo un objeto se convierte a cadena legible. Por defecto, imprimir un objeto muestra su dirección de memoria, lo que a menudo no es útil. Sobrescribir __str__ puede hacer depuración y logging mucho más claros:

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

Ahora, al imprimir un Punto, obtenemos:

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

Salida

(2, 3)

La misma representación se usa por str(p1) y format(p1) porque Python internamente llama a p1.__str__().


Sobrecargando el Operador +

Para personalizar la adición para objetos Punto, implementa __add__:

class Punto:
    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 Punto(self.x + other.x, self.y + other.y)

Probando el nuevo comportamiento:

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

Salida

(3, 5)

Bajo el capó, Python ejecuta p1.__add__(p2), que devuelve un nuevo Punto con las coordenadas sumadas.

Referencia rápida para otros operadores aritméticos y los métodos especiales a implementar:

OperadorExpresiónMétodo Especial
Adiciónp1 + p2__add__(self, other)
Sustracciónp1 - p2__sub__(self, other)
Multiplicaciónp1 * p2__mul__(self, other)
Potenciap1 ** p2__pow__(self, other)
Divisiónp1 / p2__truediv__(self, other)
División Enterap1 // p2__floordiv__(self, other)
Módulop1 % p2__mod__(self, other)
Desplazamiento Izquierdap1 << p2__lshift__(self, other)
Desplazamiento Derechap1 >> p2__rshift__(self, other)
AND Bitwisep1 & p2__and__(self, other)
OR Bitwisep1 | p2__or__(self, other)
XOR Bitwisep1 ^ p2__xor__(self, other)
NOT Bitwise~p1__invert__(self)

Sobrecargando Operadores de Comparación

La sobrecarga de operadores no se limita a aritmética. Los operadores de comparación también pueden personalizarse. Por ejemplo, para comparar puntos basados en su distancia al origen, sobrescribe __lt__:

class Punto:
    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

Uso:

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

Otros métodos de comparación siguen un patrón similar:

OperadorExpresiónMétodo Especial
Menor Quep1 < p2__lt__(self, other)
Menor o Igualp1 <= p2__le__(self, other)
Igualp1 == p2__eq__(self, other)
Distintop1 != p2__ne__(self, other)
Mayor Quep1 > p2__gt__(self, other)
Mayor o Igualp1 >= p2__ge__(self, other)

Definiendo cuidadosamente estos métodos, puedes hacer que objetos personalizados participen naturalmente en contextos aritméticos y de comparación, mejorando legibilidad y mantenibilidad del código.

python

  1. Dominando tipos de datos en Python: Guía práctica
  2. Dominando operadores en Python: Guía completa
  3. Dominando la sentencia pass en Python: Guía práctica
  4. Dominando argumentos de funciones en Python: Posicionales, por palabra clave y por defecto
  5. Dominando Diccionarios en Python: Creación, Manipulación y Técnicas Avanzadas
  6. Dominando la Herencia en Python: Conceptos, Sintaxis y Ejemplos Prácticos
  7. Dominando Iteradores en Python: Cómo Funcionan y Cómo Crear los Tuyos
  8. Explicación de Closures en Python: Cómo las Funciones Anidadas Capturan Variables
  9. Dominando el Decorador @property de Python: Getters y Setters Limpios y Compatibles
  10. Dominando datetime en Python: Guía Práctica de Fechas, Horas y Zonas Horarias
  11. Dominar time.sleep() en Python: Mejores Prácticas, Multihilo y Ejemplos Reales