Algoritmos de Programación con Python

14.4. Métodos especiales

Así como el constructor, __init__, existen diversos métodos especiales que, si están definidos en nuestra clase, Python los llamará por nosotros cuando se utilice una instancia en situaciones particulares.

14.4.1. Un método para mostrar objetos

Para mostrar objetos, Python indica que hay que agregarle a la clase un método especial, llamado __str__ que debe devolver una cadena de caracteres con lo que queremos mostrar. Ese método se invoca cada vez que se llama a la función str.

El método __str__ tiene un solo parámetro, self.

En nuestro caso decidimos mostrar el punto como un par ordenado, por lo que escribimos el siguiente método dentro de la clase Punto:

def __str__(self):
    """ Muestra el punto como un par ordenado. """
    return "(" + str(self.x) + ", " + str(self.y) + ")"

Una vez definido este método, nuestro punto se mostrará como un par ordenado cuando se necesite una representación de cadenas.

>>> p = Punto(-6,18)
>>> str(p)
'(-6, 18)'
>>> print p
(-6, 18)

Vemos que con str(p) se obtiene la cadena construida dentro de __str__, y que internamente Python llama a __str__ cuando se le pide que imprima una variable de la clase Punto.

Nota Muchas de las funciones provistas por Python, que ya hemos utilizado en unidades anteriores, como str, len o help, invocan internamente a los métodos especiales de los objetos.

Es decir que la función str internamente invoca al método __str__ del objeto que recibe como parámetro. Y de la misma manera len invoca internamente al método __len__, si es que está definido.

Cuando mediante dir vemos que un objeto tiene alguno de estos métodos especiales, utilizamos la función de Python correspondiente a ese método especial.

14.4.2. Métodos para operar matemáticamente

Ya hemos visto un método que permitía restar dos puntos. Si bien esta implementación es perfectamente válida, no es posible usar esa función para realizar una resta con el operador -.

>>> p = Punto(3,4)
>>> q = Punto(2,5)
>>> print p - q
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'Punto' and 'Punto'

Si queremos que este operador (o el equivalente para la suma) funcione, será necesario implementar algunos métodos especiales.

def __add__(self, otro):
    """ Devuelve la suma de ambos puntos. """
    return Punto(self.x + otro.x, self.y + otro.y)

def __sub__(self, otro):
    """ Devuelve la resta de ambos puntos. """
    return Punto(self.x - otro.x, self.y - otro.y)

El método __add__ es el que se utiliza para el operador +, el primer parámetro es el primer operando de la suma, y el segundo parámetro el segundo operando. Debe devolver una nueva instancia, nunca modificar la clase actual. De la misma forma, el método __sub__ es el utilizado por el operador -.

Ahora es posible operar con los puntos directamente mediante los operadores, en lugar de llamar a métodos:

>>> p = Punto(3,4)
>>> q = Punto(2,5)
>>> print p - q
(1, -1)
>>> print p + q
(5, 9)

De la misma forma, si se quiere poder utilizar cualquier otro operador matemático, será necesario definir el método apropiado.

Nota La posibilidad de definir cuál será el comportamiento de los operadores básicos (como +, -, *, /), se llama sobrecarga de operadores.

No todos los lenguajes lo permiten, y si bien es cómodo y permite que el código sea más elegante, no es algo esencial a la Programación Orientada a Objetos.

Entre los lenguajes más conocidos que no soportan sobrecarga de operadores están C, Java, Pascal, Objective C. Entre los lenguajes más conocidos que sí soportan sobrecarga de operadores están Python, C++, C#, Perl, Ruby.


Copyright (c) 2011-2014 Rosita Wachenchauzer, Margarita Manterola, Maximiliano Curia, Marcos Medrano, Nicolás Paez. La copia y redistribución de esta página se permite bajo los términos de la licencia Creative Commons Atribución - Compartir Obras Derivadas Igual 3.0 siempre que se conserve esta nota de copyright.