Metodos especiales
Contents
Ahora vamos a hablar de los métodos especiales, estos métodos que tiene la clase y que nosotros no hemos creado pero que nos son útiles.
De entrada vamos a conocer al “inicializador”, en otros lenguajes le llaman “constructor” pero este método no es mas que un inicializador de la clase (existe otro método que se llama cuando se genera una instancia de clase, pero no vamos a hablar de el por ahora).
Este método inicializador se llama __init__
. Y nos va a servir para pasar valores iniciales a la clase.
Por ejemplo, pensemos en la clase Persona, y queremos que tenga los siguientes valores desde inicio.
- Nombre
- Apellidos
- Dirección
La forma mas común es crear un inicializador y solicitarlos.
class Persona(): def __init__(self, nombre, apellidos, direccion): self.nombre = nombre self.apellidos = apellidos self.direccion = direccion
¿Que ha pasado aqui?
Definimos la clase Persona
que recibe como parámetros nombre
, apellidos
y dirección
como cada uno de estos parámetros en el metodo __init__
tendrán un alcance limitado a dicho metodo tendremos que crear unas propiedades donde colocarlos. En este caso estamos creando tres que tienen mas o menos el mismo nombre, pero hay una diferencia, tienen self.
justo antes del nombre de la variable. ¿Por que?
Como ya mencionamos self
es el el primer parámetro para cada metodo, y es una referencia a la instancia. Entonces, podemos acceder a elementos a dicha clase usando self.algo
. Si el elemento no existe entonces es creado si se coloca el signo de igual despues, es decir, si hay una asignación de valor (como con cualquier otra variable).
Entonces podemos tener una clase mas completa, por ejemplo:
class Persona(): def __init__(self, nombre, apellidos, direccion): self.nombre = nombre self.apellidos = apellidos self.direccion = direccion def get_nombre(self): return self.nombre def get_apellidos(self): return self.appellidos def get_direccion(self): return self.direccion
Y se usaria mas o menos asi:
usuario = Persona("Marco", "Islas", "Por aqui") print usuario.get_nombre() Marco print usuario.get_apellidos() Islas print usuario.get_direccion() Por aqui
__str__ / __unicode__
Otro par de métodos bien útiles al definir una clase son __str__
y __unicode__
estos dos métodos como su nombre lo indican, tienen el propósito de devolver una representación “ASCII” y una “UNICODE”, el propósito puede ser algo tan simple como “que se vea bonito al usar ‘print'” o para ahorrarnos chamba al momento de querer una versión en texto del objeto.
Agregemos el metodo __str__
y __unicode__
a nuestra clase Persona
.
class Persona(): def __init__(self, nombre, apellidos, direccion): self.nombre = nombre self.apellidos = apellidos self.direccion = direccion def __str__(self): return "%s, %s, %s" % (self.nombre, self.apellidos, self.direccion) def __unicode__(self): return u"%s, %s, %s" % (self.nombre, self.apellidos, self.direccion) def get_nombre(self): return self.nombre def get_apellidos(self): return self.apellidos def get_direccion(self): return self.direccion usuario = Persona("Marco", "Islas", "Por aqui") print (usuario,) ('Marco, Islas, Por aqui',) print (unicode(usuario),) (u'Marco, Islas, Por aqui',)
Como podemos ver en el ejemplo, print usuario
ha solicitado el método __str__
, sin embargo unicode
ha mandado a llamar el método __unicode__
, podemos ver la diferencia en que “str” imprime una cadena, pero unicode imprime una cadena con una “u” antepuesta (indicando que es unicode).
__add__
Este método como se pueden imaginar “agrega” o “suma” dos objetos a partir de una propiedad conocida. Téoricamente queremos sumar objetos del mismo tipo, al menos que tengan la misma propiedad que queremos “sumar”.
Supongamos que la clase Persona
ahora tiene la propiedad edad y que al sumar dos personas se devuelva el total de su edad.
class Persona(): def __init__(self, nombre, apellidos, direccion, edad): self.nombre = nombre self.apellidos = apellidos self.direccion = direccion self.edad = edad def __add__(self, other): return self.edad + other.edad usuario = Persona("Marco", "Islas", "Por aqui", 34) usuario2 = Persona("Fulanito", "De tal", "Por alla", 25) print usuario + usuario2 59
Claro, podemos devolver lo que queramos, por ejemplo:
class Persona(): def __init__(self, nombre, apellidos, direccion, edad): self.nombre = nombre self.apellidos = apellidos self.direccion = direccion self.edad = edad def __add__(self, other): return "%s %s vive en '%s' y %s %s vive en '%s', entre los dos suman %d de edad"%( self.nombre, self.apellidos, self.direccion, other. nombre, other.apellidos, other.direccion, self.edad + other.edad) Marco Islas vive en 'Por aqui' y Fulanito De tal vive en 'Por alla', entre los dos suman 59 de edad
Otros métodos especiales
Python es un lenguaje basado en un protocolo, por lo tanto es predecible, a cada operador le corresponde un método en cada objeto, usualmente estos métodos tienen dos guiones bajos al principio y dos al final. Si usamos la función dir()
podemos ver que métodos hay en el objeto, incluyendo sus metidos especiales:
class Persona(): def __init__(self, nombre, apellidos, direccion, edad): self.nombre = nombre self.apellidos = apellidos self.direccion = direccion self.edad = edad def __str__(self): return "%s, %s, %s" % (self.nombre, self.apellidos, self.direccion) def __unicode__(self): return u"%s, %s, %s" % (self.nombre, self.apellidos, self.direccion) def __add__(self, other): return "%s %s vive en '%s' y %s %s vive en '%s', entre los dos suman %d de edad"%( self.nombre, self.apellidos, self.direccion, other. nombre, other.apellidos, other.direccion, self.edad + other.edad) def get_nombre(self): return self.nombre def get_apellidos(self): return self.apellidos def get_direccion(self): return self.direccion usuario = Persona("Marco", "Islas", "Por aqui", 34) print dir(usuario) ['__add__', '__doc__', '__init__', '__module__', '__str__', '__unicode__', 'apellidos', 'direccion', 'edad', 'get_apellidos', 'get_direccion', 'get_nombre', 'nombre']
Otros metodos especiales son:
- __repr__ Llamado por la función “repr”
- __len__, __getitem__, __reversed__ usado en las estructuras de datos como las listas, tuplas y diccionarios, puedes entonces crear objetos parecidos a las secuencias y que puedan ser iteradas.
- __eq__, __lt__, __gt__ sinónimos de equal, less than, greater than, y se usan con los operadores “=”, “<“, “<“.
- __enter__, __exit__ Estos son útiles para cuando se usa con la palabra reservada
with
, que manda a llamar dichos métodos para ejecutar una acción cuando se entra en el bloque with (enter) o cuando se sale del bloque (enter).
You must be logged in to take the quiz.