Clases

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).

 

Loading

You must be logged in to take the quiz.