Sobrecarga de operadores

Algunos lenguajes hacen posible cambiar la definición de los operadores internos cuando se aplican a tipos definidos por el usuario. Esta característica se llama sobrecarga de operadores. Es especialmente útil cuando definimos nuevos
tipos matemáticos.

Por ejemplo, para suplantar al operador de suma + necesitamos proporcionar
un método llamado __add__ :

Como es habitual, el primer parámetro es el objeto sobre el que se invoca el método. El segundo parámetro se llama convenientemente otro para distinguirlo del mismo (self). Para sumar dos Puntos, creamos y devolvemos un nuevo Punto que contiene la suma de las coordenadas x y la suma de las coordenadas y.

Ahora, cuando apliquemos el operador + a objetos Punto, Python invocará a
__add__:

La expresión p1 + p2 equivale a p1. add (p2), pero es obviamente más elegante.

Hay varias formas de sobrecargar el comportamiento del operador multiplicación: definiendo un método llamado __mul__ , o __rmul__ , o ambos.

Si el operando a la izquierda de * es un Punto, Python invoca a __mul__ , lo que presupone que el otro operando es también un Punto. Calcula el producto interno de dos puntos, definido según las reglas de álgebra lineal:

Si el operando a la izquierda de * es un tipo primitivo y el operando de la
derecha es un Punto, Python invoca a __rmul__ , lo que realiza una multiplicación escalar:

El resultado es un nuevo Punto cuyas coordenadas son múltiplos de las coordenadas originales. Si otro es un tipo que no se puede multiplicar por un número en coma flotante, entonces rmul causará un error.

Este ejemplo muestra ambos tipos de multiplicación:

¿Qué ocurre si intentamos evaluar p2 * 2? Como el primer parámetro es un Punto, Python invoca a __mul__ con 2 como el segundo parámetro. Dentro de __mul__, el programa intenta acceder a la coordenada x de otro, pero no lo consigue porque un entero no tiene atributos:

Desgraciadamente, el mensaje de error es un poco opaco. Este ejemplo muestra algunas de las difucultades de la programación orientada a objetos. A veces es difı́cil averiguar simplemente qué código se está ejecutando.

Para ver un ejemplo más completo de sobrecarga de operadores, vaya al Apéndice B.